Fed*_*dor 2 c++ operator-overloading language-lawyer c++20
在 C++20 中,我们获得了新的三向比较operator <=>,通常返回std::strong_ordering或std::partial_ordering类型。如果类A有operator <=>,则其对象的比较a1 < a2被解释为(a1 <=> a2) < 0。
但是用户可以重载比较运算符,采用类型的第一个参数std::strong_ordering和接受文字的第二个参数0吗?例如:
#include <compare>
#include <iostream>
struct A {
std::strong_ordering operator <=>(const A &) const = default;
};
void operator < (std::strong_ordering, std::nullptr_t) {
std::cout << "overloaded< ";
}
int main() {
A{} < A{}; // #1
(A{} <=> A{}) < 0; //#2
}
Run Code Online (Sandbox Code Playgroud)
在这里,GCC 和 Clang 都调用重载operator <,即使没有任何关于标准库中存在另一个运算符的警告。可以吗?演示: https: //gcc.godbolt.org/z/zEEP45Ezj
MSVC 的行为更有趣。在 #1 中它打印了一个奇怪的错误:
error C2088: '<': illegal for struct
Run Code Online (Sandbox Code Playgroud)
在#2中:
error C2593: 'operator <' is ambiguous
<source>(8): note: could be 'void operator <(std::strong_ordering,std::nullptr_t)'
C:/data/msvc/14.30.30423-Pre/include\compare(189): note: or 'bool std::operator <(const std::strong_ordering,std::_Literal_zero) noexcept' [found using argument-dependent lookup]
<source>(14): note: while trying to match the argument list '(std::strong_ordering, int)'
Run Code Online (Sandbox Code Playgroud)
就我个人而言,我更喜欢这种行为,但是这里正确的行为是什么?
标准没有说明 的比较unspecified中的类型strong_ordering,只是它0完全接受文字(并且使用其他任何内容都是未定义的)。
0特别是,它没有指定将文字转换为参数类型所涉及的隐式转换序列的类型。如果实现使用类类型作为参数,那么您将获得一个用户定义的转换序列,该序列会输给从到 的operator<标准转换;如果它使用too,那么它是有歧义的;如果它使用,那么你的过载就会丢失。0nullptr_tnullptr_tint
只是……别这样做。
| 归档时间: |
|
| 查看次数: |
379 次 |
| 最近记录: |