为什么(删除的)复制构造函数优于隐式转换?
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);
由于f1
是Foo
类型,Foo(const Foo&)
是直接参数类型匹配。因此,在重载决策中的排名高于 Foo(const Bar&)
.
考虑以下代码:
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);
由于f1
是Foo
类型,Foo(const Foo&)
是直接参数类型匹配。因此,在重载决策中的排名高于 Foo(const Bar&)
.