Нужно ли мне определять `operator ==` для использования моего класса со стандартными контейнерами?

Я хотел бы пояснить стандарт C ++, в частности, где говорится (моя интерпретация) в разделе 20.1.3, что «для класса T и экземпляра класса T с именем x, T (x) должен быть эквивалентен x» для класса работать со стандартными контейнерами.

Я не мог найти определение «эквивалент». Означает ли это, что я должен определить operator== как член моего класса, чтобы T(x) == x возвращал истину?


person sje397    schedule 19.07.2010    source источник
comment
Я был бы признателен за правильную ссылку на стандартную документацию, чтобы я мог процитировать ее правильно, если у кого-то есть под рукой :)   -  person sje397    schedule 19.07.2010
comment
К сожалению, это не бесплатно: stackoverflow.com/questions/81656/   -  person GManNickG    schedule 19.07.2010


Ответы (2)


Эквивалент намеренно расплывчатый. (Чтобы избежать таких вещей, как наложение operator== должно быть определено; в общем случае это не так.)

Однако концептуально две вещи эквивалентны, если их данные представляют один и тот же объект. Если в классе есть данные, которые могут отличаться при «копировании», тогда вам нужно сделать operator== (и, возможно, operator< вместе с rel_ops), чтобы убедиться, что "эквивалент" реализован в отношении этого. (По сути, убедитесь, что изменяемые данные не являются «частью класса», так сказать.)

Обычно лучше не идти по этому пути, потому что вам придется исправлять множество вещей, чтобы убедиться, что он работает должным образом. Если что-то нужно скопировать, пусть копируется полностью. В этом гораздо больше смысла.

person GManNickG    schedule 19.07.2010
comment
Я думаю, что ваше определение «правильное» (отсюда и принятие) ... но кажется крайне странным, что стандарт (который допускает ужасно нечитаемый код и вложенные шаблоны, которые поразят вас) помещает концептуальный ограничения на мой дизайн. Например, если оператор определен в моем дизайне, но я еще не набрал его, и он не используется, поэтому все равно будет оптимизирован, это будет «совместимым»? - person sje397; 19.07.2010
comment
@sje: Хех, кажется, я понимаю, к чему вы клоните. :) Я бы сказал да, в этом конкретном случае. Но для общего решения (и, следовательно, хорошего совета: P) это должно быть реализовано. - person GManNickG; 19.07.2010
comment
Также Стандартные Контейнеры определены в терминах Концепций, и их value_type должен быть частью определенного набора Концепций. Так что да, это налагает концептуальные ограничения на ваши классы в самом буквальном смысле. - person pmr; 19.07.2010

Это означает, что класс должен быть копируемым.
И что конструктор копирования создает объект, эквивалентный оригиналу.

Если вы не определите один, компилятор сгенерирует конструктор копии.
Если класс не содержит указателей, в большинстве ситуаций это должно работать нормально.

Примечание: вам не нужно определять "operator =="

person Martin York    schedule 19.07.2010
comment
Но что именно означает «эквивалент»? - person sje397; 19.07.2010
comment
Стандартные контейнеры делают копии объекта. (они копируют объект в контейнер). Пока вы согласны с тем, что скопировано, это эквивалентно. Например, скопированный в контейнер shared_pointer может не быть в точности таким же, как оригинал (может быть изменено некоторое внутреннее состояние), но он эквивалентен оригиналу. - person Martin York; 19.07.2010
comment
Разве это не зависит от контейнера? Как бы работали хеш-таблица или двоичное дерево, если бы вы не могли определить, были ли два объекта одинаковыми? - person Gabe; 19.07.2010
comment
@Gabe: Некоторым контейнерам необходимо определение оператора ‹(Sutch as Map (т.е. двоичное дерево)). Но вопрос не в этом. - person Martin York; 19.07.2010
comment
Можете ли вы дать определение «эквивалент», не используя слова «эквивалент»? :) - person sje397; 20.07.2010
comment
Я не пытаюсь дать определение, а скорее использую в контексте - person Martin York; 20.07.2010