Der folgende Code besagt, dass beim Übergeben der Karte an const
die operator[]
Methode Qualifizierer verworfen werden:
#include <iostream>
#include <map>
#include <string>
using namespace std;
class MapWrapper {
public:
const int &get_value(const int &key) const {
return _map[key];
}
private:
map<int, int> _map;
};
int main() {
MapWrapper mw;
cout << mw.get_value(42) << endl;
return 0;
}
Liegt dies an der möglichen Zuordnung, die beim Kartenzugriff auftritt? Können keine Funktionen mit Kartenzugriffen als const deklariert werden?
MapWrapper.cpp:10: error: passing ‘const std::map<int, int, std::less<int>, std::allocator<std::pair<const int, int> > >’ as ‘this’ argument of ‘_Tp& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const _Key&) [with _Key = int, _Tp = int, _Compare = std::less<int>, _Alloc = std::allocator<std::pair<const int, int> >]’ discards qualifiers
Antworten:
std::map
'soperator []
wird nicht als deklariertconst
und kann nicht auf sein Verhalten zurückzuführen sein:Infolgedessen kann Ihre Funktion nicht deklariert
const
werden und verwendet die Karteoperator[]
.std::map
Mit derfind()
Funktion können Sie einen Schlüssel nachschlagen, ohne die Karte zu ändern.find()
Gibt einiterator
oderconst_iterator
zu einem zurück,std::pair
das sowohl den Schlüssel (.first
) als auch den Wert (.second
) enthält.In C ++ 11 können Sie auch
at()
für verwendenstd::map
. Wenn das Element nicht vorhanden ist, löst die Funktionstd::out_of_range
im Gegensatz zu eine Ausnahme ausoperator []
.quelle
operator[]
(zBfoo[bar] = baz
) und rvalueoperator[]
(zBx = foo[bar]
) unterscheiden - letzteres könnte sicherlich const sein.Da
operator[]
es keine const-qualifizierte Überladung gibt, kann sie nicht sicher in einer const-qualifizierten Funktion verwendet werden. Dies liegt wahrscheinlich daran, dass die aktuelle Überlastung mit dem Ziel erstellt wurde, Schlüsselwerte zurückzugeben und festzulegen.Stattdessen können Sie Folgendes verwenden:
In C ++ 11 können Sie den
at()
Operator verwenden:quelle
map.find(KEY)->second;
ist unsicher, wenn die Kartenwerte Zeichenfolgen sind. Es neigt dazu, Müll zu drucken, wenn der SCHLÜSSEL nicht gefunden wird.Sie können nicht
operator[]
auf einer Karte verwenden,const
da diese Methode nichtconst
dazu dient, die Karte zu ändern (die Sie zuweisen können_map[key]
). Versuchen Sie stattdessen diefind
Methode.quelle
Einige neuere Versionen der GCC-Header (4.1 und 4.2 auf meinem Computer) haben nicht standardmäßige Elementfunktionen map :: at (), die als const deklariert sind und std :: out_of_range auslösen, wenn sich der Schlüssel nicht in der Map befindet.
Aus einem Verweis im Kommentar der Funktion geht hervor, dass dies als neue Elementfunktion in der Standardbibliothek vorgeschlagen wurde.
quelle
Erstens sollten Sie keine Symbole verwenden, die mit _ beginnen, da sie der Sprachimplementierung / dem Compiler-Writer vorbehalten sind. Es wäre sehr einfach für _map, ein Syntaxfehler für den Compiler einer anderen Person zu sein, und Sie hätten nur sich selbst die Schuld zu geben.
Wenn Sie einen Unterstrich verwenden möchten, setzen Sie ihn am Ende und nicht am Anfang. Sie haben diesen Fehler wahrscheinlich gemacht, weil Sie Microsoft-Code dabei gesehen haben. Denken Sie daran, dass sie ihren eigenen Compiler schreiben, damit sie möglicherweise damit durchkommen können. Trotzdem ist es eine schlechte Idee.
Der Operator [] gibt nicht nur eine Referenz zurück, sondern erstellt tatsächlich den Eintrag in der Karte. Sie erhalten also nicht nur ein Mapping, wenn es keines gibt, erstellen Sie eines. Das haben Sie nicht beabsichtigt.
quelle
_
ist einfach falsch. Bezeichner, die mit zwei Unterstrichen (__example
) beginnen, oder Bezeichner, die mit einem Unterstrich und einem Großbuchstaben (_Example
) beginnen, sind reserviert._example
ist nicht reserviert.