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

时间:2018-12-21 08:10:27

标签: c++ initialization c++14 default-constructor

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

  

我无法确定对象w2的构造方式。

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

  

0 Widget()

首先,Widget不是aggregate type,它具有用户定义的构造函数;然后Widget w2{};执行value initialization

  

在所有情况下,如果使用一对空括号{},并且T为   聚合类型,而不是执行聚合初始化   值初始化。

     

如果T是没有默认构造函数但具有一个   构造函数采用std :: initializer_list,列表初始化为   执行。

以上两种情况在这里都是错误的。然后

  

1)如果T是没有默认构造函数或具有用户提供或删除的默认构造函数的类类型,则该对象将被默认初始化;

然后在default initialization

(重点是我的)

  

如果T是non-POD (until C++11)类类型,则考虑构造函数,并针对空参数列表对其进行重载解析。调用选定的构造函数(是默认构造函数之一)为新对象提供初始值;


BTW:Widget w1();不是变量定义,而是函数声明。它声明了一个名为w1的函数,不带任何内容并返回Widget。这就是为什么您仅获得3个输出的原因。您可能需要Widget w1;