为什么全球飞船运营商的表现不如预期?
Why does global spaceship operator not behave as expected?
#include <compare>
#include <forward_list>
template<typename T>
struct A
{
std::forward_list<T> l;
};
template<typename T>
auto operator<=>(const A<T>& lhs, const A<T>& rhs)
{
return lhs.l <=> rhs.l;
}
int main()
{
std::forward_list<int>{} < std::forward_list<int>{}; // ok
A<int>{} < A<int>{}; // error
}
使用 clang++ -std=c++20 -stdlib=libc++ main.cpp
和错误消息编译:
main.cpp:13:18: error: invalid operands to binary expression ('const std::forward_list<int>' and 'const std::forward_list<int>')
return lhs.l <=> rhs.l;
~~~~~ ^ ~~~~~
main.cpp:20:14: note: in instantiation of function template specialization 'operator<=><int>' requested here
A<int>{} < A<int>{}; // error
为什么全局飞船操作符不符合预期?
libc++(或任何标准库)似乎还没有完全实现宇宙飞船运算符库添加。
在 cppreference.com 处查看 here for libc++ and here 编译的 table。将operator<=>
添加到std::forward_list
的相关论文是P1614.
如果你查看 libc++ 的 std::forward_list
here 的源代码,你会发现还没有提到 operator<=>
并且其他辅助比较运算符仍然是无条件定义的(这在 C++20 中不应该是这种情况。
std::forward_list<int>{} < std::forward_list<int>{};
编译是因为它使用 operator<
,而不是 operator<=>
。如果您直接尝试 std::forward_list<int>{} <=> std::forward_list<int>{}
,它也会失败(在 libc++ 的当前状态下)。
#include <compare>
#include <forward_list>
template<typename T>
struct A
{
std::forward_list<T> l;
};
template<typename T>
auto operator<=>(const A<T>& lhs, const A<T>& rhs)
{
return lhs.l <=> rhs.l;
}
int main()
{
std::forward_list<int>{} < std::forward_list<int>{}; // ok
A<int>{} < A<int>{}; // error
}
使用 clang++ -std=c++20 -stdlib=libc++ main.cpp
和错误消息编译:
main.cpp:13:18: error: invalid operands to binary expression ('const std::forward_list<int>' and 'const std::forward_list<int>')
return lhs.l <=> rhs.l;
~~~~~ ^ ~~~~~
main.cpp:20:14: note: in instantiation of function template specialization 'operator<=><int>' requested here
A<int>{} < A<int>{}; // error
为什么全局飞船操作符不符合预期?
libc++(或任何标准库)似乎还没有完全实现宇宙飞船运算符库添加。
在 cppreference.com 处查看 here for libc++ and here 编译的 table。将operator<=>
添加到std::forward_list
的相关论文是P1614.
如果你查看 libc++ 的 std::forward_list
here 的源代码,你会发现还没有提到 operator<=>
并且其他辅助比较运算符仍然是无条件定义的(这在 C++20 中不应该是这种情况。
std::forward_list<int>{} < std::forward_list<int>{};
编译是因为它使用 operator<
,而不是 operator<=>
。如果您直接尝试 std::forward_list<int>{} <=> std::forward_list<int>{}
,它也会失败(在 libc++ 的当前状态下)。