继承比较运算符的 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 转换。