Почему равенство необходимо для rel_ops?Разве «<» недостаточно? </p>
a==b => !(a<b) && !(b<a)
Потому что в общем случае это не так.Если бы rel_ops
работал бы только для реляционных операторов, которые следуют этой логике, он был бы весьма ограничен.
Я предполагаю, что вы имеете в виду слабый порядок, требуемый для оператора <
для ассоциативных контейнеров.Из cppreference :
Везде, где стандартная библиотека использует требования сравнения, уникальность определяется с использованием отношения эквивалентности.В неточных терминах два объекта a и b считаются эквивалентными (не уникальными), если ни один из них не сравнивается меньше, чем другой:! Comp (a, b) &&! Comp (b, a).
Inпростые термины: то, считаются ли два ключа «одинаковыми», определяется только требованием ! (a < b) && ! (b < a)
.Следовательно, вам нужно только указать <
для ассоциативных контейнеров и не указывать operator==
, чтобы решить, являются ли два ключа одинаковыми.Однако эквивалентность (!(a<b)&&!(b<a)
) не обязательно совпадает с равенством (a==b
).
Например, когда вы используете этот
struct my_key {
int a;
int b;
bool operator< (const key_type& other) {
return a < other.a; // not comparing b !
}
};
в качестве ключа std::map
тогда my_key{1,0}
и my_key{1,2}
эквивалентны («тот же ключ»), даже если они не равны.В качестве другого примера рассмотрим Point
в сферических координатах, где мы выбираем a < b
, когда a
ближе к началу координат, чем b
:
struct Point {
double radius;
double angle;
bool operator<(const Point& other) {
return radius < other.radius;
}
bool operator==(const Point& other) {
return (radius == other.radius) && (angle == other.angle);
}
}
Также здесь все три a < b
b < a
и a == b
могут быть ложными одновременно.
Также обратите внимание, что (из cppreference )
Начиная с C ++ 20, std :: rel_ops устарел в пользу оператора <=>.
Для звездолета <=>
вы можете выбрать между
std::strong_ordering
std::weak_ordering
std::partial_ordering
std::strong_equality
std::weak_equality
Слабый заказ - это то, что требуется, например, для std::map
(например, my_key
или Point
), тогда как для сильного порядка эквивалентность и равенство в основном одинаковы.Для более подробной информации и примеров я отсылаю вас к this .