Methode nicht als konstant deklarierbar
-
Hallo,
ich habe eine Klasse "partition_tree" (nur das wesentliche)
class partition_tree { private: map<int, node*> nodes_sep; public: const node* get_node(const int i) const; };wobei
const node* partition_tree::get_node(const int i) const { return nodes_sep[i]; }Hierbei ist "node" irgendeine weitere Klasse. Der Compiler gibt nun bezüglich der Zeile
return nodes_sep[i];die Fehlermeldung
passing ‘const std::map<int, node*, std::less<int>, std::allocator<std::pair<const int, node*> > >’ as ‘this’ argument of ‘_Tp& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const _Key&) [with _Key = int, _Tp = node*, _Compare = std::less<int>, _Alloc = std::allocator<std::pair<const int, node*> >]’ discards qualifiers
aus. Wenn ich "partition_tree::get_node" nicht als konstant deklariere, tritt der Fehler nicht auf. Ich sehe jedoch nicht, inwieweit die Methode "partition_tree::get_node", die Klasse "partition_tree" verändern soll. Weiß jemand, was hier los ist?
-
probier mal
return nodes_sep.find(i)->second;
-
besser (falls i evtl kein gueltiger key...):
//bei kleiner map size return (nodes_sep.find(i)!=nodes_sep.end() ? nodes_sep.find(i)->second : NULL; //ansonsten mit tmp val arbeiten: std::map<int, node*>::cons_iterator pos=nodes_sep.find(i); if( pos== nodes_sep.end() ) return NULL; return pos->second;
-
als kleiner Zusatz die Fehlermeldung von MSVC 2008 bzgl. deiner Ursprungsversion:
: error C2678: binary '[' : no operator found which takes a left-hand operand of type 'const std::map<_Kty,_Ty>' (or there is no acceptable conversion)
with
[
_Kty=int,
_Ty=node *
]
VC\include\map(167): could be 'node *&std::map<_Kty,_Ty>::operator [](const int &)'
with
[
_Kty=int,
_Ty=node *
]
while trying to match the argument list '(const std::map<_Kty,_Ty>, const int)'
with
[
_Kty=int,
_Ty=node *
]wie du siehst greifst du per reference auf den node-ptr in der map bei Verwednung des index-op zu. Das ist in const - Methoden unzulässig, denn du koenntest das objekt ja verändern
Mit find erhälst du den node als Kopie in einem std::pair... das ist wiederum zulässig
-
der indexoperator einer map liefert dir *immer* eine gültige referenz zurück. falls er den schlüssel in der map nicht findet, wird einfach ein neuer angelegt und ein default-wert für ihn angelegt - d.h. operator[] muss die map verändern dürfen.
im übrigen solltest du bei
nodes_sep.find(i)deshalb auch überprüfen, ob der iterator auf ein gültiges element zeigt.
-
genau. und das bedeutet, dass bei return nodes_sep[i] und einem nicht vorhandenem Schluessel die map automatisch erweitert werden wuerde. das ist in einer cont-methode jedoch verboten. selbst bei eine rnicht const methode ist das gefährlich, da hier evtl ein ungueltiger pointer zurueck gegeben wird.