The following two code segments presents the task of initializing variable b
as a copy of a
. The first code segment initializes the variable using copy initialization (initialization using =
). Assume class Apple
is simply defined as an empty class: class Apple {};
Apple a;
Apple b = a;
The second code segment initializes the variable using copy initialization as well. Though what is copied in the initialization is the copy of a
.
Apple a;
Apple b = Apple(a);
When reading this blindly, it seems as if a copy happens at Apple(a)
, and another at Apple b = ...
. In contradiction, overriding the copy constructor of Apple
to print something on copy shows that only one copy happens during Apple b = Apple(a)
.
Are the two statements Apple b = a;
and Apple b = Apple(a);
identical? Are there instances where they are not identical?
Yes, in concept, for Apple b = Apple(a);
, a temporary Apple
is constructed from a
firstly, then b
is copy-initialized from the temporary. Because of copy elision, as the effect b
is initialized from a
directly.
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:
This kind of copy elision is guaranteed since C++17, before C++17 it's an optimization. Compiling with pre-C++17 mode and option prohibiting optimization, you might see the difference between the two cases.