【发布时间】:2014-02-17 06:43:43
【问题描述】:
class AAA {
public:
explicit AAA(const AAA&) {}
AAA(int) {}
};
int main() {
AAA a = 1;
return 0;
}
据我了解,在上面的代码中,尽管在大多数情况下都省略了,但在语义上仍然需要调用复制构造函数。我的问题是,调用是显式的还是隐式的?很长一段时间以来,我一直认为对 AAA::AAA(int) 的调用是隐式的,但对复制构造函数的调用却不是。今天不小心弄到g++编译上面的代码,报错了。 (VC12编译OK。)
在标准的第 8.5 节中:
如果目标类型是(可能是 cv 限定的)类类型:
如果初始化是直接初始化,或者如果是复制初始化,其中源的 cv 不合格版本 type 与该类的类相同或派生类 目的地,构造函数被考虑。适用的构造函数 枚举(13.3.1.3),通过重载选择最好的 决议(13.3)。调用如此选择的构造函数进行初始化 对象,以初始化表达式或表达式列表作为其 论点。如果没有构造函数适用,或者重载决议是 模棱两可,初始化格式不正确。
否则(即,对于剩余的复制初始化情况),可以从源转换的用户定义的转换序列 类型为目标类型或(使用转换函数时) 其派生类的枚举如 13.3.1.4 中所述, 最好的一个是通过重载决议(13.3)选择的。如果 转换无法完成或不明确,初始化是 格式不正确。使用初始化程序调用所选函数 表达式作为其参数;如果函数是构造函数,则调用 初始化 cv 不合格版本的临时版本 目的地类型。临时是prvalue。调用结果 (这是构造函数的临时情况)然后用于 direct-initialize,根据上面的规则,对象就是 复制初始化的目的地。在某些情况下,一个 允许实施以消除在此固有的复制 通过直接构造中间结果来直接初始化 进入正在初始化的对象;见 12.2、12.8。
上面引号中的粗体direct-initialize 表示对复制构造函数的调用是显式的,对吗?是 g++ 错了还是我对标准的解释错了?
【问题讨论】:
标签: c++ g++ language-lawyer