Как определить конструктор, который вызывается с пустым инициализатором? - PullRequest
0 голосов
/ 21 декабря 2018

Я тестировал следующий код на двух разных компиляторах, я не мог определить, как создается объект w2.

#include<iostream>
using namespace std;
class Widget
{
public:
    Widget()
    {
        std::cout <<count++<<" "<< __FUNCTION__ << "()"<< std::endl;

    }
    Widget(std::initializer_list<int> il)
    {
        std::cout <<count++<< " " <<__FUNCTION__ << "(std::initializer_list<int> il)" << std::endl;
    }
private:
    static int count;
};
int Widget::count = 0;
int main()
{

    Widget w1();
    Widget w2{};
    Widget w3{ 10, 5 };
    Widget w4({});
}

на обоих компиляторах вывод:

0 Widget()
1 Widget(std::initializer_list<int> il)
2 Widget(std::initializer_list<int> il)

1 Ответ

0 голосов
/ 21 декабря 2018

Я не мог определить, как создается объект w2.

w2 создается конструктором по умолчанию;как видно из вывода

0 Widget()

Во-первых, Widget не является агрегатным типом , он имеет определяемый пользователемконструкторы;затем Widget w2{}; выполняет инициализацию значения .

Во всех случаях, если используется пустая пара фигурных скобок {} и T является агрегатным типом, вместо этого выполняется инициализация агрегатазначения-инициализации.

Если T является типом класса, который не имеет конструктора по умолчанию, но имеет конструктор, принимающий std :: initializer_list, выполняется инициализация списка.

Оба приведенных выше случаяЛожь здесь.Затем

1) если T является типом класса без конструктора по умолчанию или с предоставленным пользователем или удаленным конструктором по умолчанию, объект инициализируется по умолчанию;

затемв инициализация по умолчанию ,

(выделение моя)

, если T является типом класса non-POD (until C++11), конструкторы рассматриваются и подвергаются разрешению перегрузки относительнопустой список аргументов.Выбранный конструктор (, который является одним из конструкторов по умолчанию ) вызывается для предоставления начального значения для нового объекта;


Кстати: Widget w1(); не являетсяопределение переменной, но объявление функции;которая объявляет функцию с именем w1, которая ничего не берет и возвращает Widget.Вот почему вы получаете только 3 выхода.Возможно, вы захотите Widget w1;.

...