为什么全球太空飞船运营商的行为不符合预期?

时间:2020-04-08 08:08:09

标签: c++ clang standards c++20 spaceship-operator

#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

为什么全球太空飞船操作员的行为不符合预期?

1 个答案:

答案 0 :(得分:3)

似乎libc ++(或任何标准库)尚未完全实现对飞船操作员库的添加。

请参阅here for libc++here,以获取cppreference.com上的已编译表。将operator<=>添加到std::forward_list的相关论文是P1614。

如果查看std::forward_list here的libc ++源代码,您会发现没有提到operator<=>,并且其他二级比较运算符仍然是无条件定义的(不应在C ++ 20中会如此)。

std::forward_list<int>{} < std::forward_list<int>{};会进行编译,因为它使用的是operator<,而不是operator<=>。如果直接尝试std::forward_list<int>{} <=> std::forward_list<int>{},它也会失败(在libc ++的当前状态下)。