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-nonqualified版本的源 type与类的类相同,或者是类的派生类 目的地,建设者被考虑。适用的构造函数 列举(13.3.1.3),并通过过载选择最好的一个 决议(13.3)。如此选择的构造函数被调用以初始化 对象,初始化表达式或表达式列表作为其对象 参数(一个或多个)。如果没有构造函数适用,或者重载解析是 暧昧,初始化是不正确的。
否则(即,对于剩余的复制初始化情况),可以从源转换的用户定义的转换序列 键入目标类型或(使用转换函数时) 按照13.3.1.4的描述列举其派生类别, 并且通过重载决策(13.3)选择最好的一个。如果 转换不能完成或模糊,初始化是 病态的。使用初始化程序调用所选的函数 表达作为其论点;如果函数是构造函数,则调用 初始化一个临时的cv-nonqualified版本的 目的地类型。临时是一个prvalue。通话的结果 (然后用于构造函数的临时情况) 直接初始化,根据上面的规则,对象就是 复制初始化的目的地。在某些情况下, 允许实现消除此中固有的复制 通过直接构造中间结果直接初始化 进入被初始化的对象;见12.2,12.8。
上面引号中的粗体direct-initialize
表示对复制构造函数的调用是显式的,对吧? g ++是错误的还是我对标准的解释错了?
答案 0 :(得分:3)
看起来像这个错误:g++ fails to call explicit constructors in the second step of copy initialization
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)是一个 直接初始化,应考虑显式构造函数 作为候选人的职能。
答案 1 :(得分:1)
看起来永远不会调用复制构造函数。只调用构造函数。以下代码可以调用复制构造函数
AAA a = 1;
AAA ab = a;
不确定为什么G ++正在编译它。