如何确定用空大括号初始化程序调用的构造函数?

how to determine the constructor which called with empty braced initializer?

我在两个不同的编译器上测试了以下代码,我无法确定对象 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)

I could not determine how the object w2 is constructed.

w2由默认构造函数构造;从输出中可以看出

0 Widget()

首先,Widget 不是 aggregate type, it has user-defined constructors; then Widget w2{}; performs value initialization

In all cases, if the empty pair of braces {} is used and T is an aggregate type, aggregate-initialization is performed instead of 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.

以上两种情况在这里都是错误的。那么

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;

然后在 default initialization,

(强调我的)

if T is a non-POD (until C++11) class type, the constructors are considered and subjected to overload resolution against the empty argument list. The constructor selected (which is one of the default constructors) is called to provide the initial value for the new object;


BTW:Widget w1();不是变量定义,而是函数声明;它声明了一个名为 w1 的函数,不接受任何内容并返回 Widget。这就是为什么你只能得到 3 个输出。你可能想要 Widget w1;.