为什么有一个基类会使一个类不合格?

lee*_*ewz 9 c++ c++11

有一个聚合公共基类(甚至多个聚合公共基类)会使一个类失去聚合类的优良属性是什么意思?

"聚合基类"的定义来自 http://en.cppreference.com/w/cpp/language/aggregate_initialization http://en.wikipedia.org/wiki/C++_classes#Aggregate_classes


聚合类的优良属性:

  • 在不定义构造函数的情况下,可以通过传入括号括起的值列表来初始化其成员(或基类,如果他们允许的话)来初始化聚合类型.
  • 聚合类型被认为是"简单的"(POD的概括),并且可以用作文字类型以用于constexprs的目的.

来自http://en.cppreference.com/w/cpp/language/aggregate_initialization#Example的初始化初始示例:

#include <string>
#include <array>
struct S {
  int x;
  struct Foo {
    int i;
    int j;
    int a[3];
  } b;
};

int main()
{
  S s1 = { 1, { 2, 3, {4, 5, 6} } };
  S s2 = { 1, 2, 3, 4, 5, 6}; // same, but with brace elision
}
Run Code Online (Sandbox Code Playgroud)

另请参阅: 什么是聚合和POD以及它们如何/为何特殊?

aar*_*man 3

这是 c++11 标准中聚合的定义,这就是我所能给出的全部内容,而无需试图猜测委员会在做出此决定时的想法。

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

粗体表示聚合没有基类。

至于其他答案提出的继承问题,您可以通过继承进行统一初始化。注意:A 仍然是一个聚合。

struct A {                                                                         
    int val_A;                                                                                                                        
};                                                                                 

struct B : public A {                                                              
    int val_B;                                                                     
    B(int a, int b) : A{a}, val_B(b) {}                                            
};                                                                                 
int main() {                                                                       
    B b {2,3};                                                                     
    return 0;                                                                      
}  
Run Code Online (Sandbox Code Playgroud)

你只需给 B 一个构造函数,IMO 标准可以很容易地选择它作为默认值。聚合可能被保留,因为它们在以前的标准中,但事实是,对于 c++11 功能,您实际上甚至不需要它们。事实上,一个问题是std::array需要双括号,因为它没有初始化列表构造函数,我认为这个问题在 c++14 中已经解决了。

我想补充一点,鉴于统一初始化和初始值设定项列表的新功能,我不知道聚合会为类添加多少内容。

  • 那么你的答案不妨改写为“因为标准是这么说的”。我并不是说这一定是错误的答案,只是你的答案,按照目前的写法,完全回避了这个问题。 (6认同)