2009-05-25 2 views
23

Я пытаюсь назначить настраиваемый тип в качестве ключа для std :: map. Вот тип, который я использую как ключ.Пользовательские типы как ключ для карты - 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; 
}; 

При использовании станд :: Карта, я получаю следующее сообщение об ошибке.

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 

Если я изменил структуру, как показано ниже, все сработало.

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

Ничего не изменилось, кроме изготовления перегрузок оператора в друга. Мне интересно, почему мой первый код не работает?

Любые мысли?

ответ

32

Я подозреваю, что вам нужно

bool operator<(const Foo& foo1) const; 

Обратите внимание на const после аргументов, это сделать «ваш» (левая рука в сравнении) объекта постоянны.

Причина, по которой нужен только один оператор, заключается в том, что этого достаточно, чтобы реализовать требуемый порядок. Чтобы ответить на абстрактный вопрос, «нужно ли придти до б?»? достаточно знать, меньше ли а.

+0

Спасибо. Это сделал трюк. –

+0

Можете ли вы подробнее остановиться? Зачем вам нужен оператор <, а не оператор == или оператор>? – bobobobo

+14

, потому что вы можете вывести оператор> и оператор == из оператора <. '(b b)', поэтому есть оператор>. и, '(! (A skrebbel

3

Возможно, он ищет операторы-члены-члены (независимо от правильного имени). Это работает (примечание Const):

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

EDIT: удален operator> из моего ответа, как это было не нужно (копирование/вставка из вопроса), но это привлекало комментарии :)

Примечание: Я 100% уверен, что вам понадобится const, потому что я скомпилировал пример.

+2

Вам не нужно> –

+0

Забавный stackoverflow показывает предыдущий ответ 10 минут назад, но когда я отправляю свой ответ, еще не было ... отсюда тот же ответ – stefanB

+0

Так как объект постоянный, функция const будет необходима. – siddhusingh

0

Обратите внимание на константу после аргументов, это значит, что объект «ваш» (левая сторона в сравнении) постоянный.

Не могли бы вы рассказать об этом? Почему, если вы создаете член const (который, насколько я знаю, означает, что он не может изменить состояние объекта, например, изменять частные переменные) гарантирует, что «ваш» будет левым?

0

Не могли бы вы рассказать об этом? Почему, если вы создаете член const (который, насколько я знаю, означает, что он не может изменить состояние объекта, например, изменять частные переменные) гарантирует, что «ваш» будет левым?

У меня еще нет комментариев прокомментировать это.

const не волшебным образом гарантирует, что «ваш» будет левым. Плакат говорил, что левая сторона (т. Е. X в x < y) является объектом, по которому вызывается сравнение. Так же, как вы защищаете члены y от изменения с помощью константы в аргументе оператору <, вы также хотите защитить члены x от изменения с помощью константы в конце подписи метода.

Смежные вопросы