Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why copy constructor is called in std::vector's initializer list?

I have the following very simple class:

class Foo 
{
public:
  Foo() {}
  Foo(const Foo&) = delete;
  Foo(Foo&&) {}

  void operator=(const Foo&) = delete;
  void operator=(Foo&&) {}

  void dump() const {}
};

The class is move constructible and assignable but isn't copy constructible and assignable.

I'd like to initialize a vector of Foo elements using vector's initializer list.

std::vector<Foo> vf = { Foo() };

The compiler complains because code has to use the deleted copy constructor. Could anybody explain, why the move construct is not used in this case, and why copy of the object is needed?

The following also requires the copy constructor and does not work either:

std::vector<Foo> vf = { std::move(Foo()) };

On the other hand, this works fine (the move constructor is called):

std::vector<Foo> vf;
vf.push_back(Foo());

Thanks for the explanation... :)

Update:

A suggested this post explains my question.

Furthermore let's consider the following code (together with class Foo above):

class Bar {
public:
    Bar(std::initializer_list<Foo> _l) {
        std::cout << "Bar::Bar()" << std::endl;
        for (auto& e : _l)
            e.dump();
    }
};

int main() {
    Bar b { Foo() };
    return 0;
}

This produces the following output (compiled with C++11):

Foo::Foo()
Bar::Bar()
Foo::dump()
Foo::~Foo()

It can be seen, that the initializer list is not actually filled with the 'copy of the objects' stated between the braces. This might be not true from C++14.

like image 900
Peter Avatar asked Apr 05 '16 08:04

Peter


People also ask

Does initializer list call copy constructor?

1. Copy constructor of “Type” class is called to initialize : variable(a). The arguments in initializer list are used to copy construct “variable” directly.

Does Emplace_back call copy constructor?

emplace_back():This function can directly insert the object without calling the copy constructor.

What is a constructor initializer list and what are its uses C++?

Initializer List is used in initializing the data members of a class. The list of members to be initialized is indicated with constructor as a comma-separated list followed by a colon. Following is an example that uses the initializer list to initialize x and y of Point class.

Do initializer lists copy?

And yes, the construction of the elements of the array the initializer_list references are susceptible to copy elision. Including C++17's rules for guaranteed elision.


Video Answer


1 Answers

It's specifically because you use an initializer list that the copy-constructor is used. The initializer list is initialized with a copy of the object, and then passed to the vector.

If you read the linked reference, from C++14 it even explicitly say

... each element is copy-initialized ... from the corresponding element of the original initializer list

Emphasis mine

like image 145
Some programmer dude Avatar answered Sep 17 '22 11:09

Some programmer dude