Erfundenes Beispiel für die Frage:
void MyClass::MyFunction( int x ) const
{
std::cout << m_map[x] << std::endl
}
Dies wird nicht kompiliert, da der Operator [] nicht const ist.
Dies ist bedauerlich, da die Syntax [] sehr sauber aussieht. Stattdessen muss ich so etwas tun:
void MyClass::MyFunction( int x ) const
{
MyMap iter = m_map.find(x);
std::cout << iter->second << std::endl
}
Das hat mich immer nervt. Warum ist der Operator [] nicht konstant?
operator[]
ergeben, wenn das angegebene Element nicht existiert?Antworten:
Für
std::map
undstd::unordered_map
,operator[]
den Indexwert in den Behälter einfügen , wenn es zuvor nicht vorhanden ist. Es ist ein wenig unintuitiv, aber so ist es.Da es fehlschlagen muss, einen Standardwert einzufügen, kann der Operator nicht für eine
const
Instanz des Containers verwendet werden.http://en.cppreference.com/w/cpp/container/map/operator_at
quelle
std::set
hat nichtoperator[]
.Jetzt, da Sie mit C ++ 11 eine sauberere Version haben können, verwenden Sie at ()
quelle
map
const und non-constat()
s haben - warum nicht auch füroperator[]
? mit der const version nichts einfügen sondern werfen? (Oder ein optionales zurückgeben, wenn std :: optional es in den Standardat
in zwei Varianten gibt, ist, dass es a tutreturn *this;
, und der einzige Unterschied zwischen den Überladungen ist dieconst
-ness der zurückgegebenen Referenz. Die tatsächlichen Auswirkungen beiderat
s sind genau gleich (dh keine Auswirkung).Hinweis für neue Leser.
Die ursprüngliche Frage betraf STL-Container (nicht speziell die std :: map)
Es sollte beachtet werden, dass es auf den meisten Containern eine konstante Version von operator [] gibt.
Es ist nur so, dass std :: map und std :: set keine const-Version haben und dies ist ein Ergebnis der zugrunde liegenden Struktur, die sie implementiert.
Von std :: vector
Auch für Ihr zweites Beispiel sollten Sie prüfen, ob das Element nicht gefunden werden kann.
quelle
std::set
hat überhaupt nichtoperator[]
.Da operator [] möglicherweise ein neues Element in den Container einfügt, kann es möglicherweise keine const-Member-Funktion sein. Beachten Sie, dass die Definition von Operator [] äußerst einfach ist: m [k] entspricht (* ((m.insert (value_type (k, data_type ()))). First)). Second. Genau genommen ist diese Mitgliedsfunktion nicht erforderlich: Sie existiert nur zur Vereinfachung
quelle
Ein Indexoperator sollte nur für einen schreibgeschützten Container (der in STL per se nicht wirklich vorhanden ist) const sein.
Indexoperatoren werden nicht nur zum Anzeigen von Werten verwendet.
quelle
const
, eine andereconst
- wie zstd::vector
.Wenn Sie Ihre std :: map-Mitgliedsvariable als veränderbar deklarieren
Sie können die Nicht-Const-Member-Funktionen von std :: map in Ihren Const-Member-Funktionen verwenden.
quelle
mutable
kann für Mitglieder wiestd::mutex
Caches und Debug-Helfer verwendet werden. Wenn die Karte als Cache verwendet werden soll, um eine sehr teureconst
"Getter" -Funktion zu beschleunigen ,mutable
ist dies akzeptabel. Sie müssen vorsichtig sein, aber es ist keine schreckliche Idee für sich.