2009-09-25 25 views
70

Yapmacık örneğin, söz uğruna: [] operatör const olmayan olduğuNeden STL haritaları için [] operatör const değil mi?

void MyClass::MyFunction(int x) const 
{ 
    std::cout << m_map[x] << std::endl 
} 

Bu, derlenmez. [] Sözdizimi çok temiz görünüyor beri

Bu, talihsizliktir. Bunun yerine, böyle bir şey yapmak zorunda:

void MyClass::MyFunction(int x) const 
{ 
    MyMap iter = m_map.find(x); 
    std::cout << iter->second << std::endl 
} 

Bu her zaman beni rahatsız etti. [] Operatörü neden-olmayan yapılıyor?

+4

ne olmalıdır 'operatörü []' oranlarını kullanarak daha temiz bir sürümüne sahip olabilir ile Verilen eleman mevcut değil mi? –

+1

@Frerich Raabe: Üye işleviyle aynı şey: throw std :: out_of_range –

cevap

76

std::map için, operator[] kabın içine endeksi değerini ekler. Bu biraz kasıtsız, ama işte böyle. başarısız ve bir varsayılan değer eklemek için izin verilmesi gerektiğinden

, operatör kabın bir const örneğinde kullanılamaz. Eğer

mutable std::map<...> m_map; 

Eğer const üye işlevler içinde std :: haritanın const olmayan üye işlevlerini kullanabilirsiniz değişken olmasını std :: map üye değişken bildirirseniz

http://en.cppreference.com/w/cpp/container/map/operator_at

+1

'std :: set' operatörüne sahip değil []'. – avakar

+0

Oops, bu doğru. Düzenlenen. – Alan

+0

Doğru cevap bu, ancak bir const sürümü "at" üyesi ile aynı şeyi yapabilir. Bu bir std :: out_of_range atıyor ... –

0

bir dizin operatörü sadece (gerçekten başlı başına STL içinde yok) salt okunur bir kap için const olmalıdır.

Endeksi operatörleri sadece değerlere bakmak kullanılmaz. Yeni okuyucular için

+4

Sorunun nedeni, neden iki aşırı yüklenme sürümüne sahip değil - yani bir 'const ', başka bir' const' değil - örn. std :: vector' yapar. –

26

Not.
orijinal soru STL kapları ilgiliydi (değil özellikle std :: map hakkında)

Çoğu konteynerleri operatörü [] bir const sürümü var unutulmamalıdır.
Yalnızca std :: map ve std :: set'in bir const sürümü yoktur ve bu, bunları uygulayan temel yapının bir sonucudur. std itibaren

:: vector

reference  operator[](size_type n) 
const_reference operator[](size_type n) const 

Ayrıca ikinci örneğin sen elemanı bulmak için bir başarısızlık kontrol etmelidir. daha önce var olmayan yapsam

void MyClass::MyFunction(int x) const 
{ 
    MyMap iter = m_map.find(x); 
    if (iter != m_map.end()) 
    { 
     std::cout << iter->second << std::endl 
    } 
} 
+0

'std :: set'de operatör []' yoktur. – Everyone

0

.

+13

Bu, ancak, korkunç bir fikir. – GManNickG

+0

Bu neden berbat bir fikir? –

+6

Eğer bunu yaparsanız sınıfınız için API yatıyor. Bu işlev, herhangi bir üye değişkeni değiştirmeyeceği - ancak gerçekte m_map veri üyesini değiştirebileceği anlamına gelir. – Runcible

3

Operatör [] kabın içine yeni bir öğe ekleyebileceğinden, muhtemelen bir const üye işlevi olamaz. Operatörün [] tanımının son derece basit olduğunu unutmayın: m [k], (* ((m.insert (value_type (k, data_type()))) ilk)) değerine eşdeğerdir. Açıkçası, bu üye işlevi gereksiz şudur: Şimdi yalnızca kolaylık

41

için var olduğunu C++ 11 durumunda at()

void MyClass::MyFunction(int x) const 
{ 
    std::cout << m_map.at(x) << std::endl; 
} 
+3

Eğer 'map' const (const) ve non-const (eğer 'de) varsa - neden aynı operatör için değil []'? const sürümü ile bir şey eklemek değil, daha ziyade atıyor? (Veya isteğe bağlı olarak, std :: isteğe bağlı olarak standart haline getirildiğinde) – einpoklum

+0

@einpoklum Yapı doğruluğu, çoğunlukla statik derleme zamanı denetimidir. Derleyici bir istisna atmaktan çok şikayet ettim çünkü const nesneleri doğru kullanmadım. –

İlgili konular