Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Class with a deleted copy constructor can be still copied?

I have a simple function: void foo(atomic<int> a) { }

It occurs that I can call foo() in this way: foo({ }); but I can't do it in a such way: foo(atomic<int>{ }); due to an error message copy constructor is a deleted function. I have compiled with C++14.

  1. What constructor is called in the first way: create constructor or move constructor?
  2. Why in the second way is not called for example a move constructor?
  3. These two calls of foo() compiles fine with C++17 - why?
like image 905
Michal Avatar asked Sep 10 '25 12:09

Michal


1 Answers

In foo({ });, the parameter is copy list-initialized. As the result it's initialized by the default constructor of std::atomic.

In foo(atomic<int>{ });, the parameter is copy-initialized from the temporary std::atomic (i.e. atomic<int>{ }). Before C++17 even the copy/move operation might be elided the copy/move constructor still has to be present and accessible. Since C++17 this is not required again because of mandatory copy elision, it's guaranteed that the parameter is initialized by the default constructor of std::atomic directly.

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 (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: (since C++17)

like image 87
songyuanyao Avatar answered Sep 13 '25 01:09

songyuanyao