【发布时间】:2021-02-05 13:07:32
【问题描述】:
今天升级了 Xcode(底层 clang 升级到了clang-1200.0.32.21),并开始出现类似here 描述的模棱两可的比较错误。但在那个例子中,缺少 const 很明显,而对我来说,问题似乎是继承的比较运算符。这是一个最小的例子:
struct Bar
{
bool operator==(const Bar&) const
{
return true;
}
};
struct Foo : Bar
{
using Bar::operator==;
#if defined(USE_FOO)
bool operator==(const Foo&) const
{
return true;
}
#endif
};
int main()
{
Foo a,b;
if (a == b)
{
return 0;
}
else
{
return 1;
}
}
所以,当使用clang++ -std=c++2a 编译时,它会给出:
warning: ISO C++20 considers use of overloaded operator '=='
(with operand types 'Foo' and 'Foo') to be ambiguous despite there being a
unique best viable function [-Wambiguous-reversed-operator]
if (a == b)
~ ^ ~
test.cpp:3:10: note: ambiguity is between a regular call to this operator and a
call with the argument order reversed
bool operator==(const Bar&) const
^
clang++ -std=c++2a -DUSE_FOO 有效。
是否存在破坏继承运算符使用的合法原因,或者这是 Apple clang 错误?
【问题讨论】:
-
由于引入了重写的比较运算符,有很多代码会中断。一般准则是原始代码可能没有清晰/合理的语义。话虽如此,对我来说,您的代码有什么问题并不是很明显。使用基类
operator==应该没问题。也许:p -
@cigien 好吧,是的,我可以清楚地看到强制执行适当的 constness(如链接示例中)等可能而且可能应该破坏一些东西,但在这里我只是感到困惑。
-
不只是苹果铿锵声:godbolt.org/z/h84K3r
-
我看到你已经接受了下面的答案。但是您的问题是“破坏代码的新规则是什么?”还是“为什么新规则会破坏我的代码,我做错了什么?我问过latter,但是那里的答案,以及这里的答案,基本上都是针对前者的。
-
@cigien 我对前者很感兴趣,因为我不知道类型互换性究竟是如何搞砸的。我可以接受新标准引入了重大更改(这很可悲),尽管在我的实际案例中,
using用于区分多个父类的运算符,这非常有影响。