在以下情况下,双向比较运算符应该是非成员函数:
- 您希望第一个操作数的类型不是此类
- 你想要隐式类型转换两个操作数中的任何一个
新的 C++20 三向比较运算符具有对称生成规则。表达式 的名称查找a@b
(其中@
是双向比较运算符)按顺序a@b
和a<=>b
(b<=>a
在从重载解决方案集中选择最佳匹配时出现歧义时使用此优先顺序)。有关详细信息,请参阅P0515R2。这意味着运算符<=>
可以是成员函数,并且仍然允许第一个操作数不是此类类型。
但是,该文件包含以下注释:
通常, operator<=> 应该只是一个成员函数;由于第 2.3 节中的对称生成规则,您仍将获得每个参数的转换。在极少数情况下,您还希望同时支持两个参数的转换(启用比较两个都不是此类型的对象,但使用此类型的比较函数),使其成为非成员朋友。
如果我理解正确,它说只有在需要同时对两个操作数进行隐式转换时才需要非成员实现?那是对的吗?我可以在需要时查看一个实际示例吗?我正在考虑这一点,尽管它似乎不是一个有效的例子:
struct foo
{
foo(int const x)
: data{ x } {}
foo(std::string_view x)
: data{std::stoi(x.data())}{}
friend auto operator<=>(foo const & lhv, foo const & rhv) noexcept
{
return lhv.data <=> rhv.data;
}
private:
int data;
};
int main()
{
assert(foo {42} == foo {"42"}); // OK
assert(42 == std::string_view("42")); // ??
}