2

I know about several types of initialization in C++ and recently learned why list initialization should be preferred. But what about this code? live demo

#include <iostream>
#include <string>

class A {
public:
    A(int x, std::string y) { std::cout << "normal\n"; }

    A(const A& obj) { std::cout << "copy\n"; }
};

int main(){
    A a({1, "2"}); // strange initialization
}

Prints:

normal

It looks like some kind of list initialization mixed with a construtor call using parentheses. So I thought it would create a temporary instance of A from {1, "2"} and then call the copy-constructor. But that doesn't happen. Instead it behaves like list-initialization. Maybe I'm just confused by the syntax and it is list-initialization?

If it is, how does the syntax work here? If not, what kind of initialization is this?

songyuanyao
  • 169,198
  • 16
  • 310
  • 405
Lukas-T
  • 11,133
  • 3
  • 20
  • 30
  • 3
    _It looks like some kind of list initialization mixed with a construtor call using parentheses. So I thought it would create a temporary instance of A from {1, "2"} and then call the copy-constructor._ I agree but you forgot about [copy-elision](https://en.cppreference.com/w/cpp/language/copy_elision). ;-) – Scheff's Cat May 07 '20 at 07:36

2 Answers2

4

So I thought it would create a temporary instance of A from {1, "2"} and then call the copy-constructor.

You're right. Here the object a is initialized via the constructor A::A(int x, std::string y) directly because of copy elision.

You can compile with -fno-elide-constructors option (with pre-C++17 mode, since C++17 this kind of copy elision is guaranteed), you'll get

normal
copy

LIVE

songyuanyao
  • 169,198
  • 16
  • 310
  • 405
1

A a({1, "2"}); is actually copy-list-initialization where braced-init-list is used in place of a constructor argument.

NutCracker
  • 11,485
  • 4
  • 44
  • 68