2009-05-25 6 views
23

Je suis en train d'attribuer un type personnalisé comme une clé pour std :: carte. Voici le type que j'utilise comme clé.types personnalisés comme la clé pour une carte - C++

struct Foo 
{ 
    Foo(std::string s) : foo_value(s){} 

    bool operator<(const Foo& foo1) { return foo_value < foo1.foo_value; } 

    bool operator>(const Foo& foo1) { return foo_value > foo1.foo_value; } 

    std::string foo_value; 
}; 

Lorsqu'il est utilisé avec std :: carte, j'obtiens l'erreur suivante.

error C2678: binary '<' : no operator found which takes a left-hand operand of type 'const Foo' (or there is no acceptable conversion) c:\program files\microsoft visual studio 8\vc\include\functional 143 

Si je change la structure comme ci-dessous, tout a fonctionné.

struct Foo 
{ 
    Foo(std::string s) : foo_value(s) {} 

    friend bool operator<(const Foo& foo,const Foo& foo1) { return foo.foo_value < foo1.foo_value; } 

    friend bool operator>(const Foo& foo,const Foo& foo1) { return foo.foo_value > foo1.foo_value; } 

    std::string foo_value; 
}; 

Rien n'a changé, sauf rendant les opérateurs comme les surcharges ami. Je me demande pourquoi mon premier code ne fonctionne pas?

Des pensées?

Répondre

32

Je soupçonne que vous avez besoin

bool operator<(const Foo& foo1) const; 

Notez le const après les arguments, c'est de faire « votre » (le côté gauche dans la comparaison) objet constant.

La raison pour laquelle un seul opérateur est nécessaire est qu'il suffit de mettre en œuvre la commande nécessaire. Pour répondre à la question abstraite "faut-il venir avant b?" il suffit de savoir si a est inférieur à b.

+0

Merci. Cela a fait l'affaire. –

+0

Pouvez-vous entrer dans plus de détails? Pourquoi avez-vous seulement besoin de l'opérateur ? – bobobobo

+14

parce que vous pouvez dériver l'opérateur> et l'opérateur == de l'opérateur <. '(B b)', donc il y a un opérateur>. et, '(! (A skrebbel

3

recherche très probablement pour les opérateurs membres const (quel que soit le nom correct est). Cela fonctionne (note const):

bool operator<(const Foo& foo1) const { return foo_value < foo1.foo_value;} 

EDIT: supprimé operator> de ma réponse car il n'a pas été nécessaire (copier/coller de la question), mais il attirais commentaires :)

Note: Je suis 100% sûr que vous avez besoin de const parce que j'ai compilé l'exemple.

+2

Vous n'avez pas besoin> –

+0

Fun stackoverflow affiche la réponse précédente il y a 10 minutes mais quand je soumets ma réponse il n'y en avait pas encore ... d'où la même réponse – stefanB

+0

Puisque l'objet est constante, la fonction const serait requise. – siddhusingh

0

Notez le const après les arguments, est de faire « votre » (le côté gauche dans la comparaison) objet constant.

Pourriez-vous élaborer à ce sujet? Pourquoi si vous créez le membre const (qui, pour autant que je sache, signifie qu'il ne peut pas changer l'état de l'objet - par exemple, modifier les variables privées) garantit que "votre" sera le côté gauche?

0

Pourriez-vous s'il vous plaît donner des détails à ce sujet? Pourquoi si vous créez le membre const (qui, pour autant que je sache, signifie qu'il ne peut pas changer l'état de l'objet - par exemple, modifier les variables privées) garantit que "votre" sera le côté gauche?

Je n'ai pas encore le représentant pour commenter.

const ne garantit pas comme par magie que « votre » sera le côté gauche. L'affiche indiquait que le côté gauche (c'est-à-dire x dans x < y) est l'objet sur lequel la comparaison est appelée. Tout comme vous protégez les membres de y de changer avec le const sur l'argument à l'opérateur <, vous voulez aussi protéger les membres de x de changer avec le const à la fin de la signature de la méthode.

Questions connexes