如何正确实现运算符<==>对于非 POD 课程?

发布于 01-18 16:20 字数 1182 浏览 6 评论 0 原文

我正在寻找一种实现三向比较运算符 operator == 的方法:

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 实现不是我的意图。因此,我需要编写自己的实现。

我想要的是:

  1. 我想要 equality 比较( == != )基于比较成员 m_y < /code>, m_x M_C 两个操作数(类型 foo )。所有这三个成员必须等于满足平等。 m_vec 内容的平等并不重要(因为在词典上比较所有这些元素并不有效)。
  2. 我希望订购比较(&lt; &gt; )基于比较表达式 m_y * m_x
  3. 我希望订购比较(&lt; = and &gt; = )基于比较表达式 m_y < /code> * m_x ,如果两个操作数在这方面相等,则两个操作数的所有三个成员都应等于满足&lt; = &gt; = (就像 == 中的一样)。

另外,所有这些比较类别类型都更适合此方案, std :: strong_ordering std :: feek_ordering

我应该如何实施这种逻辑?看起来很简单,我在C ++ 20书中读了整个食谱,但我仍然无法弄清楚。

I'm looking for a way to implement the three-way comparison operator and the operator== for the following 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;
};

But the default implementation is not what I intended. Therefore I need to write my own implementation.

What I want is:

  1. I want the equality comparison (== and !=) to be based on comparing the members m_Y, m_X, and m_C of two operands (of type Foo). All of those three members must be equal to satisfy the equality. The equality of the content of m_Vec is not important (since it's not efficient to compare all those elements lexicographically).
  2. I want the ordering comparison (< and >) to be based on comparing the expression m_Y * m_X.
  3. I want the ordering comparison (<= and >=) to be based on comparing the expression m_Y * m_X and if both operands are equal in that regard, then all three members of both operands should be equal to satisfy the <= or >= (just like in ==).

Also with all this said, which comparison category type suits this scenario better, std::strong_ordering or std::weak_ordering?

How should I implement such logic? It seems simple and I read a whole recipe in a C++20 book on this topic and I still can't figure it out.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

檐上三寸雪 2025-01-25 16:20:53

我相信这是一个偏序,即元素可能无法比较的顺序(<>== 都不是)夹在他们之间)。您应该验证必要的定律成立 (a <= b iff a < b || a == b, a <= a > 对于所有 aa == b 如果对于所有 a <= b &&b <= a a、ba <= c 如果 a <= b && b <= c 对于所有 ab< /代码>,<代码>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;
}

I believe this is a partial order, which is an order where elements may be incomparable (none of <, >, or == hold between them). You should verify the necessary laws hold (a <= b iff a < b || a == b, a <= a for all a, a == b if a <= b && b <= a for all a, b, and a <= c if a <= b && b <= c for all a, b, c). If that is the case, use 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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文