C++ 非默认操作员<=&燃气轮机;不';t生成==和!=在C++;20
我在C++20中遇到了一个新的宇宙飞船操作符C++ 非默认操作员<=&燃气轮机;不';t生成==和!=在C++;20,c++,c++20,spaceship-operator,C++,C++20,Spaceship Operator,我在C++20中遇到了一个新的宇宙飞船操作符的奇怪行为。我正在将Visual Studio 2019编译器与/std:c++最新版本一起使用 这段代码编译得很好,正如预期的那样: #include <compare> struct X { int Dummy = 0; auto operator<=>(const X&) const = default; // Default implementation }; int main() {
的奇怪行为。我正在将Visual Studio 2019编译器与/std:c++最新版本一起使用
这段代码编译得很好,正如预期的那样:
#include <compare>
struct X
{
int Dummy = 0;
auto operator<=>(const X&) const = default; // Default implementation
};
int main()
{
X a, b;
a == b; // OK!
return 0;
}
#包括
结构X
{
int-Dummy=0;
自动运算符(const X&)const=default;//默认实现
};
int main()
{
xa,b;
a==b;//好的!
返回0;
}
但是,如果我将X更改为:
struct X
{
int Dummy = 0;
auto operator<=>(const X& other) const
{
return Dummy <=> other.Dummy;
}
};
struct X
{
int-Dummy=0;
自动操作员(常数X和其他)常数
{
返回虚拟其他。虚拟;
}
};
我发现以下编译器错误:
错误C2676:二进制“==”:“X”未定义此运算符或到预定义运算符可接受类型的转换
我也在叮当声上试过,我得到了类似的行为
我希望您能解释一下为什么默认实现会正确地生成运算符==
,而自定义实现不会。在该功能的标准化过程中,决定在逻辑上将相等和排序分开。同样地,使用相等测试(=
和!=
)将永远不会调用操作符。然而,人们仍然认为,能够用一个声明来默认这两个选项是有用的。因此,如果您使用默认的操作符
,则决定您也要使用默认的操作符==
(除非您稍后定义它或之前定义过它)
至于,基本的推理是这样的。考虑<代码> STD::String < /代码>。两个字符串的顺序是按字典顺序排列的;每个字符都有其整数值,与另一个字符串中的每个字符进行比较。第一个不等式导致排序的结果
但是,字符串的相等性测试存在短路。如果两个字符串的长度不相等,那么进行字符级比较就毫无意义;他们不平等。所以,如果有人在做平等性测试,如果你能短路它,你就不想做冗长的测试
事实证明,许多需要用户定义顺序的类型也会为相等性测试提供一些短路机制。为了防止人们只实现操作符
而丢弃潜在的性能,我们有效地迫使每个人都这样做。这是出于设计
[class.compare.default](强调我的)
如果类定义没有显式声明==
运算符函数,但声明了默认的三向比较
运算符函数,隐式声明=
运算符函数
具有与三向比较运算符功能相同的访问权限。
类X的隐式声明的=
运算符是内联运算符
成员,并在X的定义中定义为默认值
只有默认的
允许存在合成的=
。基本原理是像std::vector
这样的类不应该使用非默认的
进行相等性测试。对=
使用
并不是比较向量的最有效方法<代码>
必须给出准确的顺序,而=
可以通过先比较大小来提前退出
如果一个类在它的三向比较中做了一些特殊的事情,那么它可能需要在它的==
中做一些特殊的事情。因此,该语言没有生成一个潜在的不合理的默认值,而是将其留给程序员来处理。其他答案很好地解释了为什么该语言是这样的。我只是想补充一点,如果不明显,当然可以让用户使用默认的操作符==
提供操作符。只需显式编写默认的运算符==
:
struct X
{
int Dummy = 0;
auto operator<=>(const X& other) const
{
return Dummy <=> other.Dummy;
}
bool operator==(const X& other) const = default;
};
struct X
{
int-Dummy=0;
自动操作员(常数X和其他)常数
{
返回虚拟其他。虚拟;
}
布尔运算符==(常量X和其他)常量=默认值;
};
这当然是明智的,除非宇宙飞船有四轮马车。但可能效率极低…@重复数据消除-敏感性是主观的。有人会说,一个无声生成的低效实现是不明智的。这个标题使得谷歌搜索时更难找到这个问题。也许应该改为非默认运算符不生成==和=代码>。我碰巧遇到了后面的人,我打算问一个类似的问题,然后自己回答。