【发布时间】:2021-09-26 13:32:30
【问题描述】:
我一直在和宇宙飞船操作员一起玩,我想知道以下行为的原因是什么:
struct ArrayWrapper
{
int arr[3];
auto operator<=>(const ArrayWrapper&) const = default;
};
ArrayWrapper a1{1,2,3}, a2{1,2,4};
auto x = a1 <=> a2; // this compiles and works, x is std::strong_ordering::less
数组比较适用于成员数组。它也适用于std::array:
std::array<int, 3> arr1{1,2,4};
std::array<int, 3> arr2{1,2,3};
auto x = arr1 <=> arr2; // x is std::strong_ordering::greater
但它不适用于非成员的原始数组:
int rawArr1[3]{1,2,3}, rawArr2[3]{1,2,3};
auto x = rawArr1 <=> rawArr2; // error: invalid operands of types ‘int [3]’ and ‘int [3]’ to binary ‘operator<=>’
我已经在 GCC 11 上测试过了。这是什么原因?考虑到它适用于数组成员,这似乎很奇怪。
【问题讨论】:
-
好问题(在我改写了它的标题之后......:-P);虽然是 IIANM,但应该直接为数组实现模板化
operator<=>()- 只需通过引用获取它们,而不是让它们衰减。 -
你的
ArrayWrapper和std::array真的没有太大区别。 C++ 中的普通数组的问题在于,它们实际上是一种单独的类型,并且是一种非常特殊的类型,它没有为它定义所有类型的操作,只是一个小而有限的集合。 -
auto x = rawArr1 < rawArr2;由于指针强制,已经意味着某些东西,因此基于值的宇宙飞船运算符可能会令人困惑和/或存在向后兼容性问题。 -
我认为可以肯定地说现在不鼓励使用普通的原始数组。它们不会使用新功能进行改造。
-
数组不是一等公民。有很多事情他们做不到,而更健壮的类型可以做到。
标签: c++ arrays language-lawyer c++20