为什么非静态数据成员初始化器会破坏统一初始化语法?

时间:2013-07-03 20:31:09

标签: c++ c++11 constructor initialization-list

如果所有类/结构数据成员都缺少初始值设定项,则可以使用统一初始化语法来构造对象。

struct foo
{
    int i;
    float f;
};
...
foo bar{ 5, 3.141f };

但是如果一个或多个成员具有初始化器,则统一初始化语法将变为无效。

struct foo
{
    int i;
    float f = 0;
};
...
foo bar{ 5, 3.141f };  // Compiler error.

我猜测添加一个数据成员初始值设定项会自动实现一个或多个默认构造函数,并禁止initialization_list构造函数的默认实现。这是预期的标准吗?为什么这样做?

1 个答案:

答案 0 :(得分:1)

是的,这是标准的意图。您在这里尝试的是聚合初始化。不幸的是,由于foo的初始化程度相同,您的第二个f不再被视为聚合。参见 8.5.1 [dcl.init.aggr] (强调我的):

  

聚合是一个数组或类(第9条),没有用户提供的构造函数(12.1),没有用于非静态数据成员的大括号或相等的初始化器(9.2),没有私有或受保护的非静态数据成员(第11条),没有基类(第10条),也没有虚函数(10.3)。

因为成员f具有相同的初始化程序,所以您需要提供自定义构造函数来支持您所使用的语法:

struct foo
{
  int i;
  float f = 0;
  constexpr foo(int i, float f) : i(i), f(f) { }
};
...
foo bar{ 5, 3.141f }; // now okay

至于为什么这是在标准中指定的,我不知道。