Комментарии 5
Если вы определили эту операцию не через default, а написали сами, проверка на равенство и неравенство не будет добавлена. Кто знает причины — пишите в комменты.
Ну вы же сами практически все уже написали: поскольку кроме std::strong_ordering для которого равенство можно вывести из <=> существуют и другие типы упорядочивания, из которых этого вывести нельзя, то решили что равенство должно быть задано явно.
А для std::strong_ordering видимо не оставили чтобы багов не плодить, которые так легко сделать внезапно поменяв возвращаемый тип…
Это не совсем так, причина там в другом. Оператор <=> вообще никогда не генерирует операторы == и != сам по себе, он генерирует только <, >, <= и >=, при этом неважно, какой ордеринг применяется. Просто есть соглашение, что дефолтные операторы == и != генерируются как бы «в довесок», если оператор <=> определен как defaulted, а так операторы «сравнения» и «равенства» как бы логически разделены и независимы. Идея была в том, что к результату выполнения operator<=>() предъявляются определенные требования, которые могут быть игнорированы при сравнении «на равенство», скажем, векторов или строк. Можно определить, что один вектор не равен другому, просто сравнив длину, и если длины разные, то сразу остановиться. Поэтому было решено, что не следует пользоваться кастомной реализацией operator<=>() для создания дефолтной реализации операторов сравнения на строгое равенство. В случае кастомной реализации operator<=>() по-прежнему можно при желании явным образом определить operator==() как default и получить его (и != соответственно). Вот здесь подробнее написано:
www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1185r2.html
www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1185r2.html
Определять полный набор операторов сравнения для пользовательских типов приходится очень редко. Обычно определяют < для сортировки и set или == и хеш для хеш таблиц. Особого восторга эта фича не вызвала.
Эта операция хороша в тех случаях когда нужно проверить на <, > и == одновременно. Со старой системой это как минимум 2 сравнения. В новой системе — это одно сравнение.
Кончно такое бывает нужно не часто, но если вдруг понадобится для больших объектов, то экономия может быть существенной.
Кончно такое бывает нужно не часто, но если вдруг понадобится для больших объектов, то экономия может быть существенной.
Обычно определяют < для сортировки и set или == и хеш для хеш таблицну вот хотите вы для структуры с несколькими полями банальные == и <, чтобы в контейнеры/алгоритмы подсовывать, даже в этом случае куда проще просто объявить дефолтный <=>, чем писать
что-то в таком духе
bool operator<(const Foo& lhs, const Foo& rhs) noexcept(...) {
return std::tie(lhs.x, lhs.y, lhs.z, ...)
< std::tie(rhs.x, rhs.y, rhs.z, ...);
}
bool operator==(const Foo& lhs, const Foo& rhs) noexcept(...) {
return std::tie(lhs.x, lhs.y, lhs.z, ...)
== std::tie(rhs.x, rhs.y, rhs.z, ...);
}
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Стандарт C++20: обзор новых возможностей C++. Часть 2 «Операция ''Космический Корабль''»