why is list initialization not invoked when initialize this class?

571 views Asked by At

according to value initialization described in this page https://en.cppreference.com/w/cpp/language/value_initialization

If T is a class type that has no default constructor but has a constructor taking std::initializer_list, list-initialization is performed.

so I was expecting when initialize the class in bellow code snippet will invoke Myclass(const std::initializer_list<int> &l) , but the compiler says

> the default constructor of "Myclass" cannot be referenced -- it is a deleted function

why is that? this is the code, I compiled with Mingw64 C++11 on windows.

#include <iostream>
class Myclass {
    public:
     Myclass() = delete;
     Myclass(Myclass &&m) {}
     Myclass(const Myclass &m) {}
     Myclass(const std::initializer_list<int> &l) { std::cout << "initializer list"; }
};
int main(int argc, char const *argv[]) {
    Myclass m2 {};
     Myclass m1={};
}
2

There are 2 answers

0
leslie.yao On BEST ANSWER

Myclass does have a default constructor; which is just marked as delete explicitly. So the effect of value-initialization should be:

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

In default-initialization the deleted default constructor is selected and the program is ill-formed.

If not to declare the default constructor as

class Myclass {
    public:
     // Myclass() = delete;
     Myclass(Myclass &&m) {}
     Myclass(const Myclass &m) {}
     Myclass(const std::initializer_list<int> &l) { std::cout << "initializer list"; }
};

Then Myclass doesn't have default constructor; (and no implicitly-declared default constructor because of other user-declared constructors). Then list-initialization is performed (as you expected), as the effect

All constructors that take std::initializer_list as the only argument, or as the first argument if the remaining arguments have default values, are examined, and matched by overload resolution against a single argument of type std::initializer_list

0
Sylvain Chaugny On

Checkout this post. in a nutshell:

  • If the default constructor is explicitly deleted, the compiler will assume there can't be any default constructor
  • If, however, you remove the Myclass() = delete; line, it will choose the best constructor, aka your initialized_list one.