johnbakers
johnbakers

Reputation: 24750

std::initializer_list and the = operator

If I do this:

 MyClass a=b;

This uses the copy constructor to initialize a, and the = operator overload is not involved, right?

The = operator would be used if a was already initialized and then I later assigned it to something else.

I saw this:

S(std::initializer_list<T> l) : v(l) {

Used like:

S<int> s = {1, 2, 3, 4, 5}; // direct list-initialization

This is interesting. It is initialization and it uses the = operator, but it is calling a constructor that is not a copy constructor. Why does it not instead take syntax like this:

S<int> s {1, 2, 3, 4, 5};

That's how the std::vector constructor with an std::initializer_list works. It seems confusing to use an = operator to initialize an object when that operator is not calling copy construction, doesn't it?

Upvotes: 3

Views: 1048

Answers (2)

Andy Prowl
Andy Prowl

Reputation: 126432

This uses the copy constructor to initialize a, and the = operator overload is not involved, right?

Exactly.

Why does it not instead take syntax like this: [...]

You can use both forms, and they are mostly equivalent, except for the fact that the form using = is called copy-list-initialization, and it requires a non-explicit constructor (thanks to Nicol Bolas for the correction).

The form without the =, on the other hand, is called direct-list-initialization and it works (quite intuitively) by directly constructing your object from the initializer (passing the initializer as an argument to the constructor of the object to-be-initialized). Whether or not the constructor is explicit is not relevant here.

So in short, the two forms are equivalent except for the fact that copy-list-initialization won't work if your constructor is explicit. If that is not the case, which form to choose is mostly a matter of style.

Upvotes: 12

Zdeslav Vojkovic
Zdeslav Vojkovic

Reputation: 14581

MyClass a=b; uses copy constructor only if b is of type MyClass.

If b was OtherClass, you would need another constructor, which is not the copy constructor, just another custom constructor taking OtherClass as argument (or more likely const OtherClass&, but that's irrelevant to the question - just preventing nitpickers :).

The same is with your example with initializer_list: It is a normal constructor for type S, which takes an initializer list as an argument. In that sense it doesn't differ from some hypothetical constructor S(int n).

Imagine if you had:

S(int n) : v(n) {}  // ctor taking an int

You could create an instance like this:

S s = 4;

The same is for initializer list.

Upvotes: 4

Related Questions