【发布时间】:2021-11-13 08:09:54
【问题描述】:
在下面的简化程序中,结构体C 继承自两个结构体A 和B。前者定义了 spaceship operator <=> 和 less 运算符,后者 - 仅定义了 spaceship 运算符。然后对C类的对象执行较少的操作:
#include <compare>
struct A {
auto operator <=>(const A&) const = default;
bool operator <(const A&) const = default;
};
struct B {
auto operator <=>(const B&) const = default;
};
struct C : A, B {};
int main() {
C c;
c.operator<(c); //ok everywhere
return c < c; //error in GCC
}
这里令人惊讶的是,显式调用 c.operator<(c) 在所有编译器中都成功,但类似的调用 c<c 被 Clang 允许但在 GCC 中被拒绝:
error: request for member 'operator<=>' is ambiguous
<source>:8:10: note: candidates are: 'auto B::operator<=>(const B&) const'
<source>:4:10: note: 'constexpr auto A::operator<=>(const A&) const'
演示:https://gcc.godbolt.org/z/xn7W9PaPc
有一个可能相关的问题:GCC can't differentiate between operator++() and operator++(int)。但是在那个问题中,显式运算符 (++) 调用被所有编译器拒绝,这与这个问题不同,显式运算符调用被所有人接受。
我以为C中只有一个operator <,它是从A派生的,根本不用考虑starship运算符。是这样吗?这里有什么编译器?
【问题讨论】:
-
你使用 C++20 编译器吗?
-
@jacobgalam starship 运算符从 C++20 开始可用。因此,它无法在没有...的情况下编译(顺便说一句。它在 Compiler Explorer 上的链接演示代码中使用。)
-
问题不在于 spaceship 运算符,问题在于多重继承,当
c < c时,您的编译器会混淆要遵循哪个路径来评估<=>运算符。
标签: c++ language-lawyer overloading multiple-inheritance c++20