如何为聚合结构实现 C(in)等式运算符?

新手上路,请多包涵

有时我有这样的结构——

 struct aggregate1 {
  std::string name;
  std::vector<ValueT> options;
  size_t foobar;
  // ...
};

-- 其中(不)平等被简单地定义为所有成员的(不)平等: lhs_name == rhs_name && lhs_options == rhs_options && lhs_foobar == rhs_foobar

实现这一点的“最佳”方式是什么? (最佳:(运行时-)效率、可维护性、可读性)

  • operator==operator!=
  • operator!=operator==
  • ==!= 的单独实现
  • 作为会员还是免费功能?

请注意,此问题仅与(不)平等操作有关,因为比较( <<= ,…)对于此类聚合没有太大意义。

原文由 Martin Ba 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 471
2 个回答

在 C++20 中,实现相等和不等运算符可以很简单,只需将 operator== 声明为 default

 struct S {
  int x;
  // ...

  // As member function
  bool operator==(S const &) const = default;

  // As non-member function (hidden friend)
  // friend bool operator==(S const &, S const &) = default;
};

If only operator== is provided, a!=b is interpreted as !(a==b) according to overload resolution, so there is no need for providing an explicit overload for operator!= .

我认为默认 operator== 作为隐藏的朋友更可取,因为它适用于引用包装的对象:

 S s;
auto rs{std::ref(s)};
rs==rs; // OK for hidden friend; ill-formed if declared as member function

在此示例中,没有为 operator== 定义 std::reference_wrapper<S> ,但参数相关查找 (ADL) 可以选择隐藏的朋友,其操作数隐式转换为 S const & 。但是请注意, ::operator==(rs,rs) 仅在 operator== 被定义为自由函数时才有效,因为不会为限定名称触发 ADL。

原文由 hcb 发布,翻译遵循 CC BY-SA 4.0 许可协议

我会这样做,但也许将 operator== 定义移动到 cpp 文件。将 operator!= 保留为内联

请记住首先比较最有可能不同的成员变量,以便将其余部分短路并且性能更好。

 struct aggregate1 {
  bool operator==(const aggregate1& rhs) const
  {
     return (name == rhs.name)
     && (options == rhs.options)
     && (foobar == rhs.foobar);
  }
  bool operator!=(const aggregate1& rhs) const
  {
    return !operator==(rhs);
  }

  std::string name;
  std::vector<ValueT> options;
  size_t foobar;

  // ...
};

原文由 T33C 发布,翻译遵循 CC BY-SA 2.5 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题