C++ 复制构造函数是可行的重载吗?
考虑以下计划:C++ 复制构造函数是可行的重载吗?,c++,language-lawyer,C++,Language Lawyer,考虑以下计划: struct A { A(int){} A(A const &){} }; int main() { A y(5); } 变量y用表达式5直接初始化。重载解析选择构造函数A::A(int),这是我所期望和想要的,但为什么会发生呢 这可能有两个原因: 要么重载A::A(int)比A::A(const&)更匹配,要么第二个重载根本不是可行的重载 问题:在上面的程序中,构造函数A::A(const&)是否是初始化y的可行重载?是的,构造函数重载的规则与普通函数相
struct A {
A(int){}
A(A const &){}
};
int main() {
A y(5);
}
变量y
用表达式5
直接初始化。重载解析选择构造函数A::A(int)
,这是我所期望和想要的,但为什么会发生呢
这可能有两个原因:
要么重载A::A(int)
比A::A(const&)
更匹配,要么第二个重载根本不是可行的重载
问题:在上面的程序中,构造函数
A::A(const&)
是否是初始化y
的可行重载?是的,构造函数重载的规则与普通函数相同。正如Ben Voigt所指出的那样,编译器允许对每个参数进行一次用户定义的转换,以便将参数与参数相匹配。在这种情况下,它可以通过A(5)
这种情况与以下情况相同:
void foo(const std::string&);
void bar(const std::string&);//1
void bar(const char*);//2
//...
foo("Hello");//Is allowed
bar("Hello");//Calls 2 as it matches exactly without a need for conversion.
因此,答案是肯定的,它是可行的重载,但没有选择它,因为根据A(int)
构造函数更匹配。:
非显式的构造函数([dcl.fct.spec])指定
将其参数类型(如果有)转换为
它的等级。这样的构造函数称为转换构造函数
[ 例如:
struct X {
X(int);
X(const char*, int =0);
X(int, int);
};
void f(X arg)
{
X a = 1; // a = X(1)
X b = "Jessie"; // b = X("Jessie",0)
a = 2; // a = X(2)
f(3); // f(X(3))
f({1, 2}); // f(X(1,2))
}
- 结束示例 ]
及
:
假设“cv1 T”是被初始化对象的类型,T是类类型,候选函数的选择如下:
(1.1)T的转换构造函数是候选函数
把问题转过来:是什么让你怀疑
A::A(const&)
可能不是一个可行的重载?你可以通过删除A(int){
。您的书中还应该介绍引用绑定规则。@nwp:不,因为这样做会改变复制构造函数的可行性。现在它是可行的,因为参数可以转换为临时a,而常量a&
可以绑定。如果删除另一个构造函数,则参数不再与常量a兼容&
。哦,我把它理解为int
vsconst int&
。忽略我所说的一切。原始代码中没有用户定义的转换。@nwp由于int
构造函数不是显式的,它是用户定义的从int
到a
对象的转换。这可能会让人困惑,但是这个问题被标记为语言律师。cppreference.com远远不规范。每个用户都适用“一次用户定义转换”的限制parameter@BenVoigt是的,谢谢。我没有指定它,因为OP的ctor只有一个参数。但是将它添加到了答案中。