为什么不能将一个简单派生的类视为聚合类型?

时间:2014-11-11 23:07:50

标签: c++ c++11 language-lawyer

来自C ++草案标准n3337

  

8.5.1聚合[dcl.init.aggr]

     

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

说我有两个班级:

struct ABase
{
   int value;
};

struct A : public ABase {};

根据标准,ABase是聚合类型,而A则不是。ABase。这意味着,可以使用:

创建ABase a1{10}; 的实例
A

但是使用:

创建A a2{20}; 的实例并不行
A

ABase通常来自A,并且可能被视为聚合。我的问题是,通过将{{1}}视为聚合类型,可能会遇到什么样的陷阱,语言的用户以及编译器的实现者?

1 个答案:

答案 0 :(得分:0)

显然我的声誉不允许我发表评论,我不确定是否可以发布,因为它可以被解释为主观,但这里有一个“语言的用户”可能会发现这个的原因概念麻烦。

初始化顺序。如果一个类具有聚合作为基础以及非静态数据成员,那么它们的初始化顺序是什么?非静态数据成员之前的基类?当然,基类何时具有基类或具有多个基类的情况如何。然后当然还有虚拟继承等。对于新手程序员来说,构造函数mem-initializer-lists中的类成员按声明顺序而不是列表顺序初始化可能会让人感到意外。我认为允许进一步混淆初始化(在这种情况下是聚合)会使语言更难学习。鉴于C ++ 11 Bjarne Stroustrup列表的目标之一是“使语言更易于教学和学习”,因此不能轻易加入混乱。当然,我意识到没有歧义,这就是为什么我避免使用这个词,它只是没有一个每个人都必须立即正确假设的命令。

我想我的观点是,通过允许基类可以获得很少的东西,这可能会导致混乱。这可能需要在标准中采用谨慎的措辞来实现这一点。