13

First attempt and everything works fine:

class Base {
 public:
    Base() {std::cout << "default ctor!\n"; }
};
...
Base b{};
Base b_one = {};

Another way of implementation(add explicit):

class Base {
 public:
    explicit Base() {std::cout << "default ctor!\n"; }
};
...
Base b{};
Base b_one = {};  // error! Why?

I have read on cppreference that in both cases default initialization would be used and no diffences.

From list initialization:

Otherwise, If the braced-init-list is empty and T is a class type with a default constructor, value-initialization is performed.

From value initialization:

if T is a class type with no default constructor or with a user-provided or deleted default constructor, the object is default-initialized;

songyuanyao
  • 169,198
  • 16
  • 310
  • 405
Gusev Slava
  • 2,136
  • 3
  • 21
  • 26

1 Answers1

18

I have read on cppreference that in both cases default initialization would be used and no diffences.

No they're not the same. To be precise, Base b{}; is direct-list-initialization, while Base b_one = {}; is copy-list-initialization; for copy-list-initialization, only non-explicit constructor may be called.

(emphasis mine)

  • direct-list-initialization (both explicit and non-explicit constructors are considered)

  • copy-list-initialization (both explicit and non-explicit constructors are considered, but only non-explicit constructors may be called)

songyuanyao
  • 169,198
  • 16
  • 310
  • 405
  • 1
    Oh, thanks. Too simple question ;) So can you help with one more? What happens when we assign to already initialized variable `b_one = {}` – Gusev Slava Aug 15 '18 at 16:18
  • 5
    @GusevSlava `operator=` will be tried to called. If the default constructor of `Base` is not `explicit`, then `{}` is implicitly converted to `Base`, then copy assignment operator (`Base::operator=(const Base&)`) is called. If the default constructor is `explict`, then it'll fail because implicit conversion fails. – songyuanyao Aug 15 '18 at 16:37