auto foo = A(123);
performs copy initialization, in concept, A(123)
constructs a temporary A
by A::A(int)
firstly, then foo
is copy-initialized from the temporary by the copy constructor (PS A
doesn't have move constructor). Before C++17 the code is ill-formed because the copy constructor is marked as delete
.
Since C++17 the copy construction is elided completely because of mandatory copy elision and the code is well-formed.
(Since C++17) First, if T
is a class type and the initializer is a prvalue expression whose cv-unqualified type is the same class as T
, the initializer expression itself, rather than a temporary materialized from it, is used to initialize the destination object: see copy elision
and
(emphais mine)
(Since C++17) 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:
Note that before C++17, copy elision is an optimization, even it might be performed the copy/move constructor still must be present and accessible.
This is an optimization: even when it takes place and the copy/move (since C++11)
constructor is not called, it still must be present and accessible (as if no optimization happened at all), otherwise the program is ill-formed:
You can upgrade your compiler to support C++17, or use direct initialization (to remove the requirement of usage of copy constructor).
A foo(123);
A foo{123};