【问题标题】:generate == operator that uses non-defaulted <=>使用非默认 <=> 生成 == 运算符
【发布时间】:2021-04-04 14:54:31
【问题描述】:

this question 略有不同。我想使用自定义&lt;=&gt; 运算符定义自定义类型,并使用该自定义&lt;=&gt; 运算符生成==。尝试以下方法

#include <compare>
#include <iostream>
#include <cassert>

struct widget {
  int member;
  int non_comparison_data;
  friend std::strong_ordering operator<=>(const widget& lhs,
                                          const widget& rhs) {
    std::cout << "doing a three way comparison" << std::endl;
    return lhs.member <=> rhs.member;
  }
//   friend bool operator==(const widget& lhs, const widget& rhs) {
//     return 0 == (lhs <=> rhs);
//   }
  friend bool operator==(const widget& lhs, const widget& rhs) = default;
};

int main() {
  widget a{.member = 1, .non_comparison_data = 23};
  widget b{.member = 1, .non_comparison_data = 42};
  assert(a==b);
  return 0;
}

我观察到默认的== 运算符不使用自定义&lt;=&gt; 运算符,而是执行在没有任何自定义比较的情况下会执行的操作并比较所有数据成员。我可以自己定义一个使用&lt;=&gt; 的运算符==,如下所示,但我想知道是否有更好的方法从&lt;=&gt; 中获取==

friend bool operator==(const widget& lhs, const widget& rhs) {{
  return 0 == (lhs <=> rhs);
}

PS:compiler-explorer link

PS:我知道自定义&lt;=&gt; 不会生成默认==,因为== 可能以比使用&lt;=&gt; 更优化的方式实现,并且人们不希望低效的默认设置是生成。

【问题讨论】:

    标签: c++ c++20 spaceship-operator


    【解决方案1】:

    我想知道是否有更好的方法让 == 脱离 。

    不,没有。您所做的 (return 0 == (lhs&lt;=&gt;rhs);) 是最佳方式。你还在寻找什么?

    【讨论】:

      【解决方案2】:

      根据&lt;=&gt; 定义== 的唯一方法是手动进行。这就是你已经在做的事情。

      您可以通过编写成员函数做得更好(非成员 friends 的唯一好处是如果您想按价值获取。但如果您不这样做,成员函数会更容易 -只需编写更少的代码)。然后实现== 向前而不是向后......请不要使用尤达条件。

      struct widget {
        int member;
        int non_comparison_data;
      
        std::strong_ordering operator<=>(const widget& rhs) const {
          return member <=> rhs.member;
        }
      
        bool operator==(const widget& rhs) const {
            return (*this <=> rhs) == 0;
        }
      };
      

      【讨论】:

      • 对于friend 部分,我在审查中被告知要保持二元运算符免费friend 函数符合核心准则C.86 isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rc-eq
      • @pseyfert 那里的描述说“B 的比较接受其第二个操作数的转换,但不是它的第一个操作数”,但在 C++20 中不再适用。所以准则(使==对称)对成员函数很满意(只要你记得consts)。
      • 布尔运算符 == 使用运算符 ;请用 C++23 ;)
      • @NoSenseEtAl No.
      猜你喜欢
      • 2020-03-05
      • 2010-10-12
      • 1970-01-01
      • 2014-04-21
      • 1970-01-01
      • 2020-08-12
      • 1970-01-01
      相关资源
      最近更新 更多