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.


Anmelden zum Antworten