副本初始化是否与副本的副本初始化相同?

Is copy initialization identical to copy initialization of a copy?

以下两个代码段介绍了将变量 b 初始化为 a 的副本的任务。第一个代码段使用 copy initialization 初始化变量(初始化使用 =)。假设 class Apple 被简单地定义为空 class:class Apple {};

Apple a;
Apple b = a;

第二个代码段也使用复制初始化来初始化变量。虽然初始化时拷贝的是a.

的拷贝
Apple a;
Apple b = Apple(a);

盲目阅读时,似乎在 Apple(a) 处出现了一个副本,在 Apple b = ... 处出现了另一个副本。矛盾的是,覆盖 Apple 的复制构造函数以在副本上打印某些内容表明在 Apple b = Apple(a).

期间只发生了一个副本

Apple b = a;Apple b = Apple(a);这两个语句是否相同?是否存在不相同的情况?

是的,在概念上,对于Apple b = Apple(a);,首先从a构造一个临时Apple,然后从临时复制初始化b。因为 copy elision,效果 b 直接从 a 初始化。

Under the following circumstances, the compilers are required to omit the copy and move construction of class objects, even if the copy/move constructor and the destructor have observable side-effects. The objects are constructed directly into the storage where they would otherwise be copied/moved to. The copy/move constructors need not be present or accessible:

  • In the initialization of an object, when the initializer expression is a prvalue of the same class type (ignoring cv-qualification) as the variable type:

这种复制省略从C++17开始是有保证的,在C++17之前是一种优化。使用 C++17 之前的模式和禁止优化的选项进行编译,您可能会看到这两种情况之间的区别。

LIVE