考虑以下示例:
#include <cstdlib>
struct A
{
A(int, char*){};
A(const A&){ printf("copy-ctor\n"); }
};
int main()
{
A x = A(5, nullptr);
}
根据 8.5.16(C++11 标准)该行
A x = A(5, nullptr);
被视为
A x(A(5, nullptr));
(即创建了一个A 类型的临时对象并将其传递给A 类型的copy-ctor 来初始化一个x)。然后根据 12.8.31 编译器被允许(但不是强制)执行称为“复制省略”的优化,以消除创建 A 类型的临时代码,从而有效地使该行代码变为
A x(5, nullptr);
(即没有创建临时对象,没有调用copy-ctors)。
现在,假设我在上面的示例中使用了列表初始化,如下所示:
A x = {5, nullptr}; // (1)
或者
A x = A{5, nullptr}; // (2)
有人可以引用 C++11 标准中的适当段落来确认或否认 (1) 和/或 (2) 将始终(即不仅当编译器可以进行“复制省略”优化时)被视为
A x(5, nullptr);
(即直接调用 A 的第一个构造函数,不创建临时对象,不复制 A 类型的对象)。