class UnusualClass
{
int a;
public:
UnusualClass(int a){std::cout<<"Direct initialization"<<std::endl;}
UnusualClass(const UnusualClass &n){std::cout<<"Copy initialization"; }
};
int main ()
{
UnusualClass k1(5); //Direct initialization
UnusualClass k2=56; //Copy initialization
return 0;
}
Why does the compiler print out "Direct initialization" twice? I've done some research and found out that I might be getting copy constructor elision.
Is it possible to get two different outcomes in these two cases?
Also, when I use UnusualClass(const UnusualClass &n)=delete
I get an error saying use of deleted function 'UnusualClass::UnusualClass(const UnusualClass&)
. Why would I get this error if it skips this constructor anyways?
I know I can get two different outcomes by using two constructors UnusualClass(int a);
and UnusualClass(double b);
but this trick doesn't seem quite right.
Copy initialization doesn't mean the copy constructor must be called.
If T is a class type, and the cv-unqualified version of the type of other is not T or derived from T, or if T is non-class type, but the type of other is a class type, user-defined conversion sequences that can convert from the type of other to T (or to a type derived from T if T is a class type and a conversion function is available) are examined and the best one is selected through overload resolution. The result of the conversion, which is a
prvalue temporary (until C++17)
prvalue expression (since C++17)
if a converting constructor was used, is then used to direct-initialize the object.The last step is usually optimized out and the result of the conversion is constructed directly in the memory allocated for the target object, but the appropriate constructor (move or copy) is required to be accessible even though it's not used. (until C++17)
In the process of this copy initialization (i.e. UnusualClass k2=56;
), UnusualClass::UnusualClass(int)
will be selected for converting int
to UnusualClass
, so it's called at first. After that the converted UnusualClass
is used to direct-initialize the object k2
, so the copy constructor is required conceptually. Before C++17 even copy elision happens the copy constructor must be accessible, that's why when you make it delete
you failed to compile. Since C++17 copy elision is guaranteed, and the copy constructor doesn't need to be accessible again.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With