三向比较取代所有其他比较运算符,除了 ==?
Three way comparison replaces all others comparison operators except ==?
在 g++ 10 中,我尝试使用三向比较,仅用于实验。
我读到其他运算符不再需要(== 除外)。
但即使我可以使用运算符(它是在编译器上实现的),它也不会取代(或暗示)!=。
所以,下面的代码是行不通的。
#include<iostream>
using namespace std;
struct A
{
struct Iterator
{
size_t index;
size_t operator*() { return index + 1000; }
//bool operator!=(const Iterator &a) const { return index != a.index; }
auto operator<=>(const Iterator &a) const { return index <=> a.index; }
Iterator &operator++() { ++index; return *this; }
};
Iterator begin() { return Iterator{0}; }
Iterator end() { return Iterator{5}; }
};
int main()
{
A a;
auto result = a.begin() <=> a.end();
for (auto b : a)
cout << b << "\n";
cout << (a.begin() != a.end()) << "\n";
return 0;
}
我在这里错过了什么?
来自cppreference:
In brief, a class that defines operator<=>
automatically gets compiler-generated operators <, <=, >, and >=. A class can define operator<=>
as defaulted, in which case the compiler will also generate the code for that operator."
不会生成 != 和 == 的代码,因此您需要执行比较。
operator ==
对于定义为默认的每个运算符 operator <=>
隐式声明为默认:
#include<iostream>
using namespace std;
struct A
{
struct Iterator
{
size_t index;
size_t operator*() { return index + 1000; }
//bool operator!=(const Iterator &a) const { return index != a.index; }
auto operator<=>(const Iterator &) const = default;
// bool operator == (const Iterator&) const; implicitly declared
Iterator &operator++() { ++index; return *this; }
};
Iterator begin() { return Iterator{0}; }
Iterator end() { return Iterator{5}; }
};
int main()
{
A a;
auto result = a.begin() <=> a.end();
for (auto b : a)
cout << b << "\n";
cout << (a.begin() != a.end()) << "\n";
return 0;
}
I read that other operators do not needed anymore (except ==).
对了,除了==
是关键位。比较运算符分为两类:
- 等式运算符(
==
、!=
)
- 排序运算符(
<=>
、<
、>
、<=
、>=
)
在每个类别中,我列出的第一个(==
和 <=>
)是 primary 比较运算符。如果您想选择加入该类别,它是您唯一需要定义的运算符。如果您想要平等,请提供 ==
。如果您想订购,请提供 <=>
(以及 ==
)。其他比较运算符是 secondary 比较运算符 - 使用次要比较的表达式在 C++20 中重写为使用主要比较运算符。
这些类别完全不同† - 没有交叉。 x != y
表达式可以调用 operator==(x, y)
甚至 operator==(y, x)
但它永远不会调用任何类型的 operator<=>
。
您的代码需要进行相等比较,但没有定义相等运算符,因此格式错误。要使其正常工作,您需要添加:
bool operator==(const Iterator &a) const { return index == a.index; }
auto operator<=>(const Iterator &a) const { return index <=> a.index; }
注意 ==
,而不是 !=
。你不应该在 C++20 中声明辅助比较运算符,除非你对它们有非常具体的需要(而这不是这样的需要)。
有关更多信息,请参阅 Comparisons in C++20。
†此规则的唯一例外是,为了方便起见,如果您 default operator<=>
那么您 也得到一个声明的,默认的operator==
。就好像你自己都违约了一样。在此示例中,由于您的比较只是默认的成员比较,您可以这样写:
auto operator<=>(const Iterator &a) const = default;
作为您的单个比较运算符声明,其行为就像您编写的那样:
bool operator==(const Iterator &a) const = default;
auto operator<=>(const Iterator &a) const = default;
这为您提供了程序所需的正确相等运算符。
在 g++ 10 中,我尝试使用三向比较,仅用于实验。
我读到其他运算符不再需要(== 除外)。
但即使我可以使用运算符(它是在编译器上实现的),它也不会取代(或暗示)!=。
所以,下面的代码是行不通的。
#include<iostream>
using namespace std;
struct A
{
struct Iterator
{
size_t index;
size_t operator*() { return index + 1000; }
//bool operator!=(const Iterator &a) const { return index != a.index; }
auto operator<=>(const Iterator &a) const { return index <=> a.index; }
Iterator &operator++() { ++index; return *this; }
};
Iterator begin() { return Iterator{0}; }
Iterator end() { return Iterator{5}; }
};
int main()
{
A a;
auto result = a.begin() <=> a.end();
for (auto b : a)
cout << b << "\n";
cout << (a.begin() != a.end()) << "\n";
return 0;
}
我在这里错过了什么?
来自cppreference:
In brief, a class that defines
operator<=>
automatically gets compiler-generated operators <, <=, >, and >=. A class can defineoperator<=>
as defaulted, in which case the compiler will also generate the code for that operator."
不会生成 != 和 == 的代码,因此您需要执行比较。
operator ==
对于定义为默认的每个运算符 operator <=>
隐式声明为默认:
#include<iostream>
using namespace std;
struct A
{
struct Iterator
{
size_t index;
size_t operator*() { return index + 1000; }
//bool operator!=(const Iterator &a) const { return index != a.index; }
auto operator<=>(const Iterator &) const = default;
// bool operator == (const Iterator&) const; implicitly declared
Iterator &operator++() { ++index; return *this; }
};
Iterator begin() { return Iterator{0}; }
Iterator end() { return Iterator{5}; }
};
int main()
{
A a;
auto result = a.begin() <=> a.end();
for (auto b : a)
cout << b << "\n";
cout << (a.begin() != a.end()) << "\n";
return 0;
}
I read that other operators do not needed anymore (except ==).
对了,除了==
是关键位。比较运算符分为两类:
- 等式运算符(
==
、!=
) - 排序运算符(
<=>
、<
、>
、<=
、>=
)
在每个类别中,我列出的第一个(==
和 <=>
)是 primary 比较运算符。如果您想选择加入该类别,它是您唯一需要定义的运算符。如果您想要平等,请提供 ==
。如果您想订购,请提供 <=>
(以及 ==
)。其他比较运算符是 secondary 比较运算符 - 使用次要比较的表达式在 C++20 中重写为使用主要比较运算符。
这些类别完全不同† - 没有交叉。 x != y
表达式可以调用 operator==(x, y)
甚至 operator==(y, x)
但它永远不会调用任何类型的 operator<=>
。
您的代码需要进行相等比较,但没有定义相等运算符,因此格式错误。要使其正常工作,您需要添加:
bool operator==(const Iterator &a) const { return index == a.index; }
auto operator<=>(const Iterator &a) const { return index <=> a.index; }
注意 ==
,而不是 !=
。你不应该在 C++20 中声明辅助比较运算符,除非你对它们有非常具体的需要(而这不是这样的需要)。
有关更多信息,请参阅 Comparisons in C++20。
†此规则的唯一例外是,为了方便起见,如果您 default operator<=>
那么您 也得到一个声明的,默认的operator==
。就好像你自己都违约了一样。在此示例中,由于您的比较只是默认的成员比较,您可以这样写:
auto operator<=>(const Iterator &a) const = default;
作为您的单个比较运算符声明,其行为就像您编写的那样:
bool operator==(const Iterator &a) const = default;
auto operator<=>(const Iterator &a) const = default;
这为您提供了程序所需的正确相等运算符。