2009-05-25 11 views
23

Estoy tratando de asignar un tipo personalizado como clave para std :: map. Este es el tipo que estoy usando como clave.Tipos personalizados como clave para un mapa - 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; 
}; 

Cuando se utiliza con std :: mapa, estoy recibiendo el siguiente error.

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 cambio la estructura como a continuación, todo funcionó.

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; 
}; 

Nada ha cambiado excepto la realización de las sobrecargas de operadores como amigo . Me pregunto por qué mi primer código no funciona.

¿Alguna idea?

Respuesta

32

sospecho que necesita

bool operator<(const Foo& foo1) const; 

Nota del const después de los argumentos, esto es hacer "su" (el lado izquierdo en la comparación) objeto constante.

La razón por la que se necesita un solo operador es que es suficiente para implementar el pedido requerido. Para responder la pregunta abstracta "¿tiene que venir antes de b?" es suficiente para saber si a es menor que b.

+0

Gracias. Eso hizo el truco. –

+0

¿Puedes entrar en más detalles? ¿Por qué solo necesita operador ? – bobobobo

+14

porque puede derivar operador> y operador == del operador <. '(b b)', por lo que hay operador>. y, '(! (A skrebbel

3

Es probable que esté buscando operadores de miembro de const (cualquiera que sea el nombre correcto). esto funciona (const nota):

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

EDITAR: suprimido operator> de mi respuesta, ya que no era necesaria (copiar/pegar de la pregunta) pero estaba atrayendo comentarios :)

Nota: No soy 100% seguro de que necesita esa const porque compilé el ejemplo.

+2

No necesita> –

+0

El stackoverflow divertido muestra la respuesta anterior hace 10 minutos, pero cuando presenté mi respuesta todavía no había ninguna ... de ahí la misma respuesta – stefanB

+0

Dado que el objeto es constante, se requeriría la función const. – siddhusingh

0

Tenga en cuenta la const después de los argumentos, esto es para hacer constante el "suyo" (el lado izquierdo en la comparación) objeto.

¿Podrían dar más detalles sobre esto? ¿Por qué si haces que el miembro const (que por lo que yo sé significa que no puede cambiar el estado del objeto, por ejemplo, modificar variables privadas) garantiza que "tu" será el lado izquierdo?

0

¿Podrías dar más detalles sobre esto? ¿Por qué si haces que el miembro const (que por lo que yo sé significa que no puede cambiar el estado del objeto, por ejemplo, modificar variables privadas) garantiza que "tu" será el lado izquierdo?

Todavía no tengo la reputación para comentar sobre esto.

const no garantiza mágicamente que "su" será el lado izquierdo. El cartel decía que el lado izquierdo (es decir, x en x < y) es el objeto sobre el que se llama la comparación. Del mismo modo que protege los miembros de y de los cambios con la const en el argumento del operador <, también desea proteger los miembros de x del cambio con la const al final de la firma del método.

Cuestiones relacionadas