2010-10-09 7 views
2

J'ai du mal à compiler quelque chose. Je ne comprends pas l'erreur rejetée par le compilateur. Un code pour illustrer le problème est ci-dessous.L'insertion avec un objet en tant que clé ne peut pas être compilée?

#include <map> 

using namespace std; 

class Thing 
{ 
public: 
    Thing(int n):val(n) {} 

    bool operator < (const Thing& rhs) const 
    { 
     return val < rhs.val; 
    } 

    int getVal() { return val; } 

private: 
    int val; 
}; 


int main(int argc, char* argv[]) 
{ 
    std::map<Thing, int> mymap; 
    Thing t1(1); 
    Thing t2(10); 
    Thing t3(5); 

    mymap[t1] = 1; // OK 

    mymap.insert(t1); // Compile error 
} 

Maintenant, le message d'erreur du compilateur:

test.cpp: In function ‘int main(int, char**)’: test.cpp:34: error: no matching function for call to ‘std::map, std::allocator > >::insert(Thing&)’ /usr/include/c++/4.4/bits/stl_map.h:499: note: candidates are: std::pair, std::_Select1st >, _Compare, typename _Alloc::rebind >::other>::iterator, bool> std::map<_Key, _Tp, _Compare, _Alloc>::insert(const std::pair&) [with _Key = Thing, _Tp = int, _Compare = std::less, _Alloc = std::allocator >] /usr/include/c++/4.4/bits/stl_map.h:539: note: typename std::_Rb_tree<_Key, std::pair, std::_Select1st >, _Compare, typename _Alloc::rebind >::other>::iterator std::map<_Key, _Tp, _Compare, _Alloc>::insert(typename std::_Rb_tree<_Key, std::pair, std::_Select1st >, _Compare, typename _Alloc::rebind >::other>::iterator, const std::pair&) [with _Key = Thing, _Tp = int, _Compare = std::less, _Alloc = std::allocator >]

Qu'est-ce que cela signifie? Y a-t-il une autre méthode ou un autre opérateur que j'ai besoin de définir dans Thing pour le compiler?

+0

La méthode 'getVal()' peut également être qualifiée '' const''. – Arun

+0

@ArunSaha - merci, c'est juste un exemple cependant. – Matt

Répondre

9

Vous avez besoin mymap.insert(std::pair<Thing,int>(t1,x));, où x est la valeur que vous souhaitez mapper à t1.

+6

Yup. Ou 'mymap.insert (std :: make_paire (t1, x));' ou 'mymap.insert (std :: map :: value_type (t1, x))'. Ce dernier devient plus utile si vous avez un 'typedef' pour' std :: map '. – aschepler

3

Vous ne pouvez pas insérer une clé (objet Thing) par lui-même - map::insert (sur votre carte au moins) prendre un std::pair<Thing,int> afin que vous insérez la valeur int indexé par clé Thing.

Cependant - il me semble que vous voulez réellement utiliser std::set<Thing>, puisque votre objet Thing a sa propre sémantique d'ordre. La répétition de int val encapsulé comme valeur dans une carte codée par Thing est redondante et rompt l'encapsulation que vous avez ici.

int main(int argc, char* argv[]) 
{ 
    std::set<Thing> myset; 
    Thing t1(1); 
    Thing t2(10); 
    Thing t3(5); 

    std::pair<std::set<Thing>::iterator, bool> result = myset.insert(t1); 

    std::set<Thing>::iterator iter = myset.find(t1); 
} 
0

s'attend à ce que vous lui transmettiez une paire valeur/clé.

mymap.insert(std::pair<Thing, int>(t2, 10)); fonctionnerait.