C++11 结构初始化编译错误

c++11 struct initialization compilation error

本文关键字:错误 编译 初始化 结构 C++11      更新时间:2023-10-16
struct SS {int a; int s;};
int main ()
{
   vector<SS> v;
   v.push_back(SS{1, 2});
}

代码可以编译而没有任何错误。但是,当结构在类中初始化时,我遇到了编译错误。谁能解释一下?

struct SS {int a = 0; int s = 2;};

错误:

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

在 C++11 中,当您在声明点使用非静态数据成员初始化时,如下所示:

struct SS {int a = 0; int s = 2;};

将类设置为非聚合类。这意味着您无法再像这样初始化实例:

SS s{1,2};

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

struct SS 
{
  SS(int a, int s) : a(a), s(s) {}
  int a = 0; 
  int s = 2;
};

这一限制已于C++14取消。

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

请参阅此处的相关阅读。

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

§ 8.5.1 聚合

聚合是一个数组或类(条款 9(,没有

用户提供的构造函数 (12.1(,没有非静态数据成员的大括号或等于初始值设定项 (9.2(,没有私有或受保护的非静态数据成员(条款 11(,没有基类(条款 10(,也没有虚函数 (10.3(。

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

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

Initialize members/elements beginning-to-end.

非聚合:

Invoke a constructor.
v.push_back(SS{1, 2}); // Error, it tries to call SS constructor

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

struct SS 
{
  SS(int a, int s) : a(a), s(s) 
  {
  }
  int a = 0; 
  int s = 2;
};

我遇到了同样的问题。就我而言,我有两个struct,它们都有几个构造函数,包括复制构造函数,继承自抽象父级。

当上面的建议没有帮助时,我终于意识到我需要从复制构造函数中删除explicit说明符,这消除了错误。

以为我会分享,以防另一个可怜的灵魂像我刚才那样花那么长时间发现这个错误。