c++ struct的聚合/指定初始化:直接引用另一个字段

Aggregate / designated initialization of c++ struct: Refer directly to another field

当使用结构的聚合/指定初始化时,可以像这样引用另一个字段:

#include <stdio.h>


int main()
{
  struct
  {
    int a;
    int b;
  }
  s = 
  {
    .a = 3,
    .b = s.a + 1,
  };

  return 0;
}

我们在s.b的初始化中使用了s.a。但是,我们需要通过s来引用s.a。是否可以将 s.a 直接引用为 .a 或类似的内容?例如,这可以在初始化结构数组时使用相同的语法,如下所示:

int main()
{
  struct
  {
    int a;
    int b;
  }
  s[] = 
  {
    {
      .a = 3,
      .b = s[0].a + 1,
    },
    {
      .a = 5,
      .b = s[1].a - 1,
    }
  };

  return 0;
}

这里我们也许可以写成 .b = .a - 1 而不是 .b = s[1].a - 1

Is it possible to refer directly to s.a as just .a, or similar?

不,.a 在此上下文中是一个 指示符,不能在 brace-or-equal-initializer 用于通过其匹配指示符初始化给定数据成员。

struct Bar { int a; };

struct Foo {
    int a;
    Bar b;
};

int main() {
    Foo f = {
     //     ^ start of braced-init-list
        .a
     // ^^ designator (for data member of Foo)
            = 1,
     //     ^^^ initializer-clause
        .b{.a = 2}
     //   ^^^^^^^^ braced-init-list
     //   referring to a designator of a 
     //   data member of Bar
    };
}

详情

指定初始化器,P0329R4, are part of the grammar for braced-init-lists 引入的新 C++20 功能:

braced-init-list:
  { initializer-list ,opt }
  { designated-initializer-list ,opt }
  { }

其中 the grammar of designated-initializer-list 是:

designated-initializer-list:
  designated-initializer-clause
  designated-initializer-list , designated-initializer-clause

并且,个人 designated-initializer-clause:s 的语法是:

designated-initializer-clause:
  designator brace-or-equal-initializer

最后,a designator 是:

designator:
  . identifier

现在,brace-or-equal-initializer 不允许以任何方式引用同一对象的 另一个 指示符。请注意指示符和 other 标识符之间的区别,例如引用结构的数据成员作为 initializer-clause 的一部分或 的嵌套 braced-init-list:s大括号或等于初始化器.