class AAA {
public:
explicit AAA(const AAA&) {}
AAA(int) {}
};
int main() {
AAA a = 1;
return 0;
}
在上面的代码中,据我了解,尽管在大多数情况下被省略,但在语义上仍然需要调用复制构造函数。我的问题是,调用是显式的还是隐式的?很长一段时间以来,我心里一直有一个结论:呼吁AAA::AAA(int)
是隐式的,但对复制构造函数的调用不是隐式的。今天无意中用g++编译上面的代码,报错。 (VC12编译正常。)
标准第 8.5 节中:
如果目标类型是(可能是 cv 限定的)类类型:
如果初始化是直接初始化,或者如果是复制初始化,其中源的 cv 不合格版本
type 是与该类相同的类,或者是该类的派生类
目的地,构造函数被考虑。适用的构造函数
被枚举(13.3.1.3),并通过重载选择最好的一个
决议(13.3)。调用如此选择的构造函数来初始化
对象,以初始化表达式或表达式列表作为其
参数。如果没有构造函数适用,或者重载决策是
不明确,初始化格式错误。
否则(即,对于其余的复制初始化情况),可以从源进行转换的用户定义的转换序列
类型转换为目标类型或(当使用转换函数时)
其派生类如 13.3.1.4 中所述枚举,
通过重载决策(13.3)选择最好的一个。如果
转换无法完成或不明确,初始化是
格式不正确。使用初始值设定项调用所选函数
表达式作为其参数;如果该函数是构造函数,则调用
初始化 cv-unqualified 版本的临时版本
目的地类型。临时值是纯右值。调用结果
(这是构造函数情况下的临时值)然后用于直接初始化,根据上述规则,该对象为
复制初始化的目的地。在某些情况下,
允许实施以消除本中固有的复制
通过直接构造中间结果直接初始化
进入正在初始化的对象;见12.2、12.8。
加粗的direct-initialize
上面的引号中意味着对复制构造函数的调用是显式的,对吗?是 g++ 错了还是我对标准的解释错了?
看起来像这个错误:g++ 在复制初始化的第二步中调用显式构造函数失败
g++ 无法编译以下代码
struct X
{
X(int) {}
explicit X(X const &) {}
};
int main()
{
X x = 1; // error: no matching function for call to 'X::X(X)'
}
复制初始化的第二步(参见 8.5/16/6/2)是
应考虑显式构造函数的直接初始化
作为候选函数。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)