Пользовательские типы в качестве ключа для карты - C ++ - PullRequest
23 голосов
/ 25 мая 2009

Я пытаюсь назначить пользовательский тип в качестве ключа для std :: map . Вот тип, который я использую в качестве ключа.

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

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

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

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

Есть мысли?

Ответы [ 4 ]

32 голосов
/ 25 мая 2009

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

bool operator<(const Foo& foo1) const;

Обратите внимание на <strong>const</strong> после аргументов, это делает объект "ваш" (левая часть в сравнении) объектом постоянным.

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

3 голосов
/ 25 мая 2009

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

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

РЕДАКТИРОВАТЬ: удалил operator> из моего ответа, поскольку он не был необходим (скопировать / вставить из вопроса), но это привлекало комментарии:)

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

0 голосов
/ 03 октября 2012

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

У меня пока нет представителя, чтобы комментировать это.

const волшебным образом не гарантирует, что "ваше" будет с левой стороны. Плакат говорил, что левая сторона (то есть х в х <у) - это объект, по которому вызывается сравнение. Так же, как вы защищаете члены y от изменений с помощью const в аргументе для оператора <, вы также хотите защитить члены x от изменений с помощью const в конце сигнатуры метода. </p>

0 голосов
/ 09 июня 2011

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...