为什么(删除的)复制构造函数优于隐式转换?

Why is (deleted) copy constructor preferred over implicit conversion?

考虑以下代码:

struct Bar{};

struct Foo
{
    Foo() = default;
    Foo(const Bar&) {}
    Foo(const Foo&) = delete;

    // IMPLICIT conversion to Bar
    operator Bar(){return {};}
};

int main() 
{
    Foo f1;
    Foo f2(static_cast<Bar>(f1)); // this is OK
    Foo f3(f1); // does not compile, why not implicit conversion to `Bar`?
}

class Bar 有一个用户定义的转换运算符到 Foo,它接受 Bar&。然而,在 main 的最后一行,我本以为 Foo f1 会被转换为 Bar,然后传递给 Foo(const Bar&)。但是,只考虑删除的构造函数Foo(const Foo&) = delete;。我知道这个构造函数是一个更好的匹配,但为什么 Foo(const Bar&) 不也在重载集中,为什么编译器不执行隐式转换?

这是首选,因为查找和重载解析发生在已删除的定义被删除的成员函数上之前。

也就是说,重载解析不会考虑 delete 说明符,并且在您的调用中:

Foo f3(f1);

由于f1Foo类型,Foo(const Foo&)是直接参数类型匹配。因此,在重载决策中的排名高于 Foo(const Bar&).