为什么 std::rel_ops 需要相等运算符?
Why does std::rel_ops need equality operator?
为什么 rel_ops 需要平等?
"<" 还不够吗?
a==b => !(a<b) && !(b<a)
这可能是一个非常愚蠢的问题。我错过了什么吗?
Why is equality needed for rel_ops? Isn't "<" enough?
a==b => !(a<b) && !(b<a)
因为一般情况下并非如此。如果 rel_ops
仅适用于遵循该逻辑的关系运算符,那将是相当有限的。
我猜您想到的是关联容器的 <
运算符所需的弱排序。来自 cppreference:
Everywhere the standard library uses the Compare requirements,
uniqueness is determined by using the equivalence relation. In
imprecise terms, two objects a and b are considered equivalent (not
unique) if neither compares less than the other: !comp(a, b) &&
!comp(b, a).
简单来说:两个键是否被认为是 "same" 仅通过要求 ! (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}
是等价的 ("same key"),即使它们不相等。作为另一个例子,考虑球坐标中的 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
也可以同时为 false。
另请注意(来自 cppreference)
As of C++20, std::rel_ops are deprecated in favor of operator<=>.
对于 starship operator <=>
你可以选择
std::strong_ordering
std::weak_ordering
std::partial_ordering
std::strong_equality
std::weak_equality
弱排序是std::map
(例如my_key
或Point
)所需要的,而强排序等价和相等性基本相同。有关更多详细信息和示例,请参阅 this.
是的,实际上你错过了某事。这是非常基本的。它与 C++ 或编程无关。这是关于数学的。根据数学,当且仅当“<”在其操作数域上定义了严格的 weak ordering 时,您的陈述才是正确的。并非每个具有 "less" rel_op 的用户定义类型都具有弱排序。
为什么 rel_ops 需要平等? "<" 还不够吗?
a==b => !(a<b) && !(b<a)
这可能是一个非常愚蠢的问题。我错过了什么吗?
Why is equality needed for rel_ops? Isn't "<" enough?
a==b => !(a<b) && !(b<a)
因为一般情况下并非如此。如果 rel_ops
仅适用于遵循该逻辑的关系运算符,那将是相当有限的。
我猜您想到的是关联容器的 <
运算符所需的弱排序。来自 cppreference:
Everywhere the standard library uses the Compare requirements, uniqueness is determined by using the equivalence relation. In imprecise terms, two objects a and b are considered equivalent (not unique) if neither compares less than the other: !comp(a, b) && !comp(b, a).
简单来说:两个键是否被认为是 "same" 仅通过要求 ! (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}
是等价的 ("same key"),即使它们不相等。作为另一个例子,考虑球坐标中的 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
也可以同时为 false。
另请注意(来自 cppreference)
As of C++20, std::rel_ops are deprecated in favor of operator<=>.
对于 starship operator <=>
你可以选择
std::strong_ordering
std::weak_ordering
std::partial_ordering
std::strong_equality
std::weak_equality
弱排序是std::map
(例如my_key
或Point
)所需要的,而强排序等价和相等性基本相同。有关更多详细信息和示例,请参阅 this.
是的,实际上你错过了某事。这是非常基本的。它与 C++ 或编程无关。这是关于数学的。根据数学,当且仅当“<”在其操作数域上定义了严格的 weak ordering 时,您的陈述才是正确的。并非每个具有 "less" rel_op 的用户定义类型都具有弱排序。