c ++ 11 struct initialization compilation error

Mic*_*l D 23 c++ c++11

struct SS {int a; int s;};

int main ()
{
   vector<SS> v;
   v.push_back(SS{1, 2});
}
Run Code Online (Sandbox Code Playgroud)

可以编译代码而不会出现任何错误.但是,当在类中初始化struct时,我得到了编译错误.有人能解释一下吗?

struct SS {int a = 0; int s = 2;};
Run Code Online (Sandbox Code Playgroud)

错误:

In function ‘int main()’:
error: no matching function for call to ‘SS::SS(<brace-enclosed initializer list>)’
     v.push_back(SS{1, 2});
                        ^
note: candidates are:
note: constexpr SS::SS()
 struct SS {int a = 0; int s = 2;};
        ^
note:   candidate expects 0 arguments, 2 provided
note: constexpr SS::SS(const SS&)
note:   candidate expects 1 argument, 2 provided
note: constexpr SS::SS(SS&&)
note:   candidate expects 1 argument, 2 provided
Run Code Online (Sandbox Code Playgroud)

jua*_*nza 32

在C++ 11中,当你在声明点使用非静态数据成员初始化时,就像你在这里一样:

struct SS {int a = 0; int s = 2;};
Run Code Online (Sandbox Code Playgroud)

你使这个类成为一个非聚合的.这意味着你不能再像这样初始化一个实例:

SS s{1,2};
Run Code Online (Sandbox Code Playgroud)

要使此初始化语法适用于非聚合,您必须添加一个双参数构造函数:

struct SS 
{
  SS(int a, int s) : a(a), s(s) {}
  int a = 0; 
  int s = 2;
};
Run Code Online (Sandbox Code Playgroud)

这个限制已在C++ 14中取消.

请注意,您可能希望为该类添加默认构造函数.用户提供的构造函数的存在会禁止编译器生成默认值.

请参阅相关阅读这里.

  • C++ 14将不再将具有类内初始化程序的类排除在聚合之外; 见http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3653.html (4认同)
  • 是的,我即将回答类似的问题.通过添加自定义构造函数`SS(){}`,可以看出没有C++ 11特性. (3认同)

bil*_*llz 5

使用默认成员初始值设定项将类/结构呈现为非聚合:

§ 8.5.1 聚合

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

聚合和非聚合的语义不同:

聚合(例如,数组和结构):

Initialize members/elements beginning-to-end.
Run Code Online (Sandbox Code Playgroud)

非聚合:

Invoke a constructor.

v.push_back(SS{1, 2}); // Error, it tries to call SS constructor
Run Code Online (Sandbox Code Playgroud)

这意味着您现在需要一个构造函数:

struct SS 
{
  SS(int a, int s) : a(a), s(s) 
  {
  }
  int a = 0; 
  int s = 2;
};
Run Code Online (Sandbox Code Playgroud)