简体   繁体   中英

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

When using aggregate / designated initialization of a struct it is possible to refer to another field like this:

#include <stdio.h>


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

  return 0;
}

We use sa in the initialization of sb However, we need to refer to sa through s. Is it possible to refer directly to sa as just .a , or similar? This would for instance make it possible to use the same syntax when initializing arrays of structs like here:

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

  return 0;
}

Here we could maybe write something like .b =.a - 1 instead of .b = s[1].a - 1 .

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

No, .a in this context is a designator , and it cannot be referred to in the brace-or-equal-initializer used to initialize a given data member by means of its matching designator.

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
    };
}

Details

Designated initializers, a new C++20 feature introduced by P0329R4 , are part of the grammar for braced-init-lists :

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

where the grammar of designated-initializer-list is:

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

and, where the grammar for the individual designated-initializer-clause :s is:

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

and where finally, a designator is:

 designator: . identifier

Now, a brace-or-equal-initializer does not allow, in any way, to refer to another designator of the same object. Note here the difference here between designators and other identifiers, eg referring to data members of the struct as part of the initializer-clause or nested braced-init-list :s of the brace-or-equal-initializer .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM