Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Empty initializer list as argument doesn't call default constructor

The following code

class A {
public:
    A() {} // default constructor
    A(int i) {} // second constructor
};
int main() {
    A obj({});
}

calls the second constructor. Probably the empty initializer_list is treated as one argument and is converted to int. But when you remove the second constructor from the class, it calls the default constructor. Why?

Also, I understand why A obj { {} } will always call a constructor with one argument as there we are passing one argument which is an empty initializer_list.

like image 601
sanjivgupta Avatar asked Mar 18 '18 17:03

sanjivgupta


People also ask

Does initializer list call constructor?

An initialization list can be used to explicitly call a constructor that takes arguments for a data member that is an object of another class (see the employee constructor example above). In a derived class constructor, an initialization list can be used to explicitly call a base class constructor that takes arguments.

Can a default constructor be empty?

A default constructor is a constructor which can be called with no arguments (either defined with an empty parameter list, or with default arguments provided for every parameter).

Does initializer list run before constructor?

An initializer list starts after the constructor name and its parameters. The list begins with a colon ( : ) and is followed by the list of variables that are to be initialized – all of​ the variables are separated by a comma with their values in curly brackets.

Does a default constructor have arguments?

Like all functions, a constructor can have default arguments. They are used to initialize member objects. If default values are supplied, the trailing arguments can be omitted in the expression list of the constructor.


1 Answers

The presence of the parentheses surrounding the braces in A obj({}); indicates the single argument constructor will be called, if possible. In this case it is possible because an empty initializer list, or braced-init-list, can be used to value initialize an int, so the single argument constructor is called with i=0.

When you remove the single argument constructor, A obj({}); can no longer call the default constructor. However, the {} can be used to default construct an A and then the copy constructor can be called to initialize obj. You can confirm this by adding A(const A&) = delete;, and the code will fail to compile.

like image 120
Praetorian Avatar answered Sep 24 '22 00:09

Praetorian