提问人:glades 提问时间:9/12/2023 最后编辑:πάντα ῥεῖglades 更新时间:9/12/2023 访问量:104
让编译器通过 spaceship-operator [duplicate] 编写运算符==、<、> 等
Letting compiler write operator==, <, > etc. via spaceship-operator [duplicate]
问:
我正在和宇宙飞船操作员碰碰运气。假设我有一个类似变体的对象(我使用固定的模板参数方便地从中派生),并且我想定义运算符 ==、<、>、!= 等......为了便于比较,我想我可以根据包含的类型来飞船,并让编译器自己定义所有运算符:std::variant
#include <compare>
#include <iostream>
#include <variant>
#include <string>
class JSON : public std::variant<std::monostate, double, std::string> {
public:
using variant::variant;
auto operator<=>(std::string str) const {
return std::get<std::string>(*this) <=> str;
}
auto operator<=>(double d) const {
return std::get<double>(*this) <=> d;
}
};
int main()
{
JSON myjson = 2.3;
if (myjson == 2.3) {
std::cout << "JSON was 2.3" << std::endl;
}
}
然而,这个 apporach 产生了:
<source>: In function 'int main()':
<source>:22:16: error: no match for 'operator==' (operand types are 'JSON' and 'double')
22 | if (myjson == 2.3) {
| ~~~~~~ ^~ ~~~
| | |
| JSON double
我本来以为编译器现在知道如何为我的变体对象编写,以防 rhs 是双精度或 rhs 是字符串。如果变体包含不同的替代方案,我可以使用 std::get 向我抛出。operator==
答:
3赞
wohlstad
9/12/2023
#1
根据任何运算符<=>重载的规则,默认的 <=> 重载>还允许将类型与 <、<=、> 和 >= 进行比较。
如果 operator<=> 是默认值,并且根本没有声明 operator==, 则 operator== 是隐式默认的。
正如您在上面的链接中看到的,这是唯一提到的基于 的隐式默认值。operator==
operator<=>
如果您的情况不是 ed,因此上述内容不适用。
因此,您需要提供(或者在一般情况下,如果可能的话,根据操作数类型自行提供)。operator<=>
default
operator==
default
注意:
正如@康桓瑋所评论的那样,在您的具体情况下,您实际上可以:default
operator<=>
auto operator<=>(const JSON& d) const = default;
如上所述,它之所以有效,是因为被转换为 ,因此比较两个 s 将调用 的比较方法。double
JSON
JSON
variant
评论
0赞
glades
9/12/2023
你能添加如何解决它吗(参见@康桓瑋对OP的评论)?
0赞
HolyBlackCat
9/12/2023
默认值不是根据 ,而是通过直接比较字段来实现它,不是吗?如果操作数类型不匹配,我认为您不能默认它。==
<=>
1赞
wohlstad
9/12/2023
@glades添加了更新。
0赞
wohlstad
9/12/2023
@HolyBlackCat我认为你是对的。添加了说明。
评论
operator==
仅当声明为 时才合成,这不是您的情况,因此仍然需要为您的类提供。operator<=>
default
operator==
auto operator<=>(const JSON& d) const = default
auto operator<=>(const JSON& d) const = default
double
JSON
JSON
variant
double
JSON
variant