来自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}}视为聚合类型,可能会遇到什么样的陷阱,语言的用户以及编译器的实现者?
答案 0 :(得分:0)
显然我的声誉不允许我发表评论,我不确定是否可以发布,因为它可以被解释为主观,但这里有一个“语言的用户”可能会发现这个的原因概念麻烦。
初始化顺序。如果一个类具有聚合作为基础以及非静态数据成员,那么它们的初始化顺序是什么?非静态数据成员之前的基类?当然,基类何时具有基类或具有多个基类的情况如何。然后当然还有虚拟继承等。对于新手程序员来说,构造函数mem-initializer-lists中的类成员按声明顺序而不是列表顺序初始化可能会让人感到意外。我认为允许进一步混淆初始化(在这种情况下是聚合)会使语言更难学习。鉴于C ++ 11 Bjarne Stroustrup列表的目标之一是“使语言更易于教学和学习”,因此不能轻易加入混乱。当然,我意识到没有歧义,这就是为什么我避免使用这个词,它只是没有一个每个人都必须立即正确假设的命令。
我想我的观点是,通过允许基类可以获得很少的东西,这可能会导致混乱。这可能需要在标准中采用谨慎的措辞来实现这一点。