如何在 C++ 中使用派生聚合的指定初始化?

How to use designated initialization of derived aggregates in C++?

我有一个聚合结构 B 来自另一个聚合 A。我想初始化它,有两个选项:普通聚合初始化和 C++20 指定初始化器:

struct A {};
struct B : A { int x; };

int main() {
    [[maybe_unused]] B x{{},1}; //ok everywhere
    [[maybe_unused]] B y{.x=1}; //warning in GCC
}

普通初始化 {{},1} 工作正常,但在这种情况下看起来太笨拙了,因为父聚合有额外的 {}

指定初始化器{.x=1}在这里对我来说看起来更好,但它们在 GCC 中会产生一个奇怪的警告:

warning: missing initializer for member 'B::<anonymous>' [-Wmissing-field-initializers]
    6 |     [[maybe_unused]] B y{.x=1}; //warning in GCC
      |                              ^

演示:https://gcc.godbolt.org/z/8jEYY16c6

有没有办法在这里使用designated initializers同时让GCC冷静下来消除warning?

Is there a way to use designated initializers here and calm down GCC at the same time to eliminate the warning?

没有。 GCC 的警告是正确的:您缺少基数 class、A 的初始化器。现在,在这种情况下,您碰巧想要从 = {} 初始化(当您不提供初始化程序时会发生这种情况),这是您唯一可以 可以 初始化的东西它来自,所以也许在这种特定情况下发出警告有点愚蠢(但在基本 class 实际上有成员的一般情况下,这是完全合理的)。此外,警告可能更有用,实际上会告诉您缺少哪个成员的初始值设定项...

不幸的是,实际上没有办法在指定初始化程序列表命名基class,它意味着无法使用指定的初始化程序实际初始化 B

有人提议解决此问题 (P2287),其目的是允许 B{.A={}, .x=1},但这仍在进行中。

您的代码有效,警告正确;你缺少一个初始化器,它将被聚合初始化。

您可以使用标志 -Wno-missing-field-initializers 禁用警告。

demo