为什么从 C++20 开始这段代码就变得模糊不清了?
template <typename T>
struct base_widget {
bool operator==(T const&) const;
};
struct gadget : base_widget<gadget> {};
bool foo(gadget const& a, gadget const& b) {
return a == b;
}
对于 MSVC,这是一个错误:
error C2666: 'base_widget<gadget>::operator ==': overloaded functions have similar conversions
could be 'bool base_widget<gadget>::operator ==(const T &) const'
with
[
T=gadget
]
or 'bool base_widget<gadget>::operator ==(const T &) const' [synthesized expression 'y == x']
with
[
T=gadget
]
while trying to match the argument list '(const gadget, const gadget)'
对于 GCC 来说这是一个警告:
In function 'bool foo(const gadget&, const gadget&)':
warning: C++20 says that these are ambiguous, even though the second is reversed:
| return a == b;
| ^
note: candidate 1: 'bool base_widget<T>::operator==(const T&) const [with T = gadget]'
| bool operator==(T const&) const;
| ^~~~~~~~
note: candidate 2: 'bool base_widget<T>::operator==(const T&) const [with T = gadget]' (reversed)
另外还有对 Clang 的警告:
warning: ISO C++20 considers use of overloaded operator '==' (with operand types 'const gadget' and 'const gadget') to be ambiguous despite there being a unique best viable function [-Wambiguous-reversed-operator]
| return a == b;
| ~ ^ ~
note: ambiguity is between a regular call to this operator and a call with the argument order reversed
| bool operator==(T const&) const;
|
我知道 C++20 允许这样做:
表达式中的重载解析/运算符
[过度匹配]
对于相等运算符,对于表达式 y == x 的每个非重写候选,重写候选还包括一个合成候选,其中两个参数的顺序被反转。
但是为什么在这种情况下合成的逆运算符是有问题的呢?
编辑:制作operator==
afriend
修复了这个问题:
template <typename T>
struct base_widget {
friend bool operator==(T const&, T const&);
};
为什么在这种情况下逆转没有问题?