聚合初始化可以引用聚合中先前的元素吗?

3
以下内容是否合法?
class Aggregate {
public:
    int a;
    int b;
};

class Class {
public:
    Class():
        m_aggregate{
            3,
            // Here, m_aggregate.a is fully constructed, but m_aggregate is not
            m_aggregate.a + 5
        } {
    }
    Aggregate m_aggregate;
};

在聚合体的生命周期开始后但聚合体构造函数完成之前,使用聚合体的元素是否合法?

使用gcc 4.8.2测试似乎表现正常...


1
clang 似乎对此发出了警告,但是即使您明确启用了 -Wuninitialized,gcc 也不会发出警告。 - user1508519
@remyabel:在clang上有关于未初始化类成员的具体工作,但可能在gcc中没有重复。 - Matthieu M.
1个回答

5
我不认为这是合法的。的确,在大括号列表中,元素是按顺序初始化的(即列表元素的评估是有序的,参见8.5.4/4),但聚合体只有在列表完全构造后才会被构建。参见8.5.1: 当一个聚合体通过初始化器列表进行初始化时,如8.5.4所规定的那样,初始化器列表的元素被视为聚合体成员的初始值,以递增的下标或成员顺序。每个成员从相应的初始化器子句中进行复制初始化。 为了从某些东西进行复制初始化,原始对象首先需要存在。

同样的推理是否适用于在构造函数中调用引用先前初始化变量的成员函数? - David Stone
@DavidStone:不完全是这样,因为类初始化的细节实际上是有规定的。在构造函数内部,对象正在“建设”中,您可以在有限的范围内使用类成员,但必须非常小心(例如,不要调用调用外部函数的东西,而是假定完全构造的对象等)。 - Kerrek SB

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接