如何为非 POD class 正确实施 operator<=>?
How to properly implement operator<=> for a non-POD class?
我正在寻找一种方法来实现 三向比较运算符 和 运算符== 以下 class:
class Foo
{
public:
auto operator<=>( const Foo& rhs ) const noexcept = default;
private:
std::uint32_t m_Y;
std::uint32_t m_X;
char m_C;
std::vector<char> m_Vec;
};
但是 default
实现不是我想要的。因此我需要编写自己的实现。
我想要的是:
- 我希望 相等 比较(
==
和 !=
)基于比较成员 m_Y
、m_X
,以及两个操作数(Foo
类型)的 m_C
。所有这三个成员都必须相等才能满足相等性。 m_Vec
的内容是否相等并不重要(因为按字典顺序比较所有这些元素效率不高)。
- 我希望 排序 比较(
<
和 >
)基于比较表达式 m_Y
* m_X
.
- 我希望 排序 比较(
<=
和 >=
)基于比较表达式 m_Y
* m_X
如果两个操作数在这方面是相等的,那么两个操作数的所有三个成员都应该相等以满足 <=
或 >=
(就像在 ==
).
综上所述,哪种比较类别类型更适合这种情况,std::strong_ordering
或 std::weak_ordering
?
我应该如何实现这样的逻辑?这看起来很简单,我在一本关于这个主题的 C++20 书中阅读了整个食谱,但我仍然无法弄明白。
我相信这是一个偏序,这是一个元素可能无法比较的顺序(<
、>
或 ==
中的 none 在它们之间).您应该验证必要的法律成立 (a <= b
iff a < b || a == b
, a <= a
对于所有 a
, a == b
如果 a <= b && b <= a
对于所有 a
、b
和 a <= c
(如果 a <= b && b <= c
用于所有 a
、b
、c
)。如果是这种情况,请使用 std::partial_ordering
.
std::partial_ordering operator<=>(Foo const &other) const noexcept {
// compare your * expression first
std::partial_ordering ret = (this->m_Y * this->m_X) <=> (other.m_Y * other.m_X);
if(ret != 0) return ret;
// if that's not informative, compare the fields
return std::tie(this->m_Y, this->m_X, this->m_C) == std::tie(other.m_Y, other.m_X, other.m_C)
? std::partial_ordering::equivalent : std::partial_ordering::unordered;
}
我正在寻找一种方法来实现 三向比较运算符 和 运算符== 以下 class:
class Foo
{
public:
auto operator<=>( const Foo& rhs ) const noexcept = default;
private:
std::uint32_t m_Y;
std::uint32_t m_X;
char m_C;
std::vector<char> m_Vec;
};
但是 default
实现不是我想要的。因此我需要编写自己的实现。
我想要的是:
- 我希望 相等 比较(
==
和!=
)基于比较成员m_Y
、m_X
,以及两个操作数(Foo
类型)的m_C
。所有这三个成员都必须相等才能满足相等性。m_Vec
的内容是否相等并不重要(因为按字典顺序比较所有这些元素效率不高)。 - 我希望 排序 比较(
<
和>
)基于比较表达式m_Y
*m_X
. - 我希望 排序 比较(
<=
和>=
)基于比较表达式m_Y
*m_X
如果两个操作数在这方面是相等的,那么两个操作数的所有三个成员都应该相等以满足<=
或>=
(就像在==
).
综上所述,哪种比较类别类型更适合这种情况,std::strong_ordering
或 std::weak_ordering
?
我应该如何实现这样的逻辑?这看起来很简单,我在一本关于这个主题的 C++20 书中阅读了整个食谱,但我仍然无法弄明白。
我相信这是一个偏序,这是一个元素可能无法比较的顺序(<
、>
或 ==
中的 none 在它们之间).您应该验证必要的法律成立 (a <= b
iff a < b || a == b
, a <= a
对于所有 a
, a == b
如果 a <= b && b <= a
对于所有 a
、b
和 a <= c
(如果 a <= b && b <= c
用于所有 a
、b
、c
)。如果是这种情况,请使用 std::partial_ordering
.
std::partial_ordering operator<=>(Foo const &other) const noexcept {
// compare your * expression first
std::partial_ordering ret = (this->m_Y * this->m_X) <=> (other.m_Y * other.m_X);
if(ret != 0) return ret;
// if that's not informative, compare the fields
return std::tie(this->m_Y, this->m_X, this->m_C) == std::tie(other.m_Y, other.m_X, other.m_C)
? std::partial_ordering::equivalent : std::partial_ordering::unordered;
}