继承比较运算符的 Apple clang 和 C++20 运算符歧义
Apple clang and C++20 operator ambiguity with inherited comparison operator
今天升级 Xcode(底层 clang 上升到 clang-1200.0.32.21
),并开始出现如 所述的模棱两可的比较错误。但在那个例子中,缺少 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 错误?
是using声明。如果省略它,一切都会按预期进行。基 class 中定义的运算符是通过名称查找找到的,提供了一个候选者(相同的隐式转换,顺序相反),一切都很好。这是 using 声明的作用
[over.match.funcs]
4 For non-conversion functions introduced by a using-declaration
into a derived class, the function is considered to be a member of the
derived class for the purpose of defining the type of the implicit
object parameter.
基本上,using 声明的行为就像您声明的那样
bool operator==(const Bar&) const
在Foo
。因此,当名称查找找到 operator==
时,左侧参数被认为是 Foo
。这位成员,当re-written,提供了两个候选人
bool operator==(const Foo&, const Bar&);
bool operator==(const Bar&, const Foo&);
现在我们遇到了与另一个问题完全相同的问题。不是 const-qualification 转换,而是 derived-to-base 转换。
今天升级 Xcode(底层 clang 上升到 clang-1200.0.32.21
),并开始出现如
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 错误?
是using声明。如果省略它,一切都会按预期进行。基 class 中定义的运算符是通过名称查找找到的,提供了一个候选者(相同的隐式转换,顺序相反),一切都很好。这是 using 声明的作用
[over.match.funcs]
4 For non-conversion functions introduced by a using-declaration into a derived class, the function is considered to be a member of the derived class for the purpose of defining the type of the implicit object parameter.
基本上,using 声明的行为就像您声明的那样
bool operator==(const Bar&) const
在Foo
。因此,当名称查找找到 operator==
时,左侧参数被认为是 Foo
。这位成员,当re-written,提供了两个候选人
bool operator==(const Foo&, const Bar&);
bool operator==(const Bar&, const Foo&);
现在我们遇到了与另一个问题完全相同的问题。不是 const-qualification 转换,而是 derived-to-base 转换。