2

I am trying to figure out a way to use designated initializers to build a struct, which has been extended off of another one. In my use case, the struct S is a domain object, and the struct S2 adds some application-specific logic for converting it to/from json. As far as I can tell, you cannot use designated initializers if you have a "real" constructor, but all is well if you have a static method returning a new instance for you.

I have a MVP like so (view in Godbolt):

#include <iostream>

struct S {
    int i;
};

struct S2 : public S {
    static S2 create() {
        return S2 { .i = 1234 };
    }
};

int main() {
    std::cout << S2::create().i;
}

When building (using -std=c++20), I get the following error:

<source>:9:31: error: 'S2' has no non-static data member named 'i'
    9 |         return S2 { .i = 1234 };
      |                               ^

I expect that the i field would be carried over and initialized, but it isn't.

Am I trying to do something C++ cannot support?

Dosisod
  • 307
  • 2
  • 15

1 Answers1

3

i is data member of S, but not S2.

You can add another braces referring to the base subobject, e.g.

return S2 { {.i = 1234} };

Or you can just take advantage of brace elision:

return S2 { 1234 };
songyuanyao
  • 169,198
  • 16
  • 310
  • 405