Home > OS >  Using Designated Initializer on member of inherited base class
Using Designated Initializer on member of inherited base class

Time:06-08

I created a class Something which holds a member variable.

I am able to do this, which works as intended:

struct Something
{
    bool Works;
};

int main()
{
    Something s = {
        .Works = false,
    };
}

Now, I want to created a struct inherited from Something, named Something2, and want to do the same thing, but I want to be able to have access to Something::Works (which I renamed DoesntWork, since it doesn't work!):

struct Something
{
    bool DoesntWork;
};

struct Something2 : public Something
{
    bool Works;
};


int main()
{
    Something2 s2 = {
        .Works = true,
        .DoesntWork = false,
    };
}

https://godbolt.org/z/rYT3br467

I am not looking for an alternative, I can already think of some. I am only wondering if this is possible, and if yes then how.

If it is not possible, I would really like to know the low-level reason, so don't hesitate!

UPDATE: Thanks to Nathan Oliver's comment, you can read: Designated initializers in C 20

CodePudding user response:

C is much stricter when it comes to designated initializers than C.

cppreference:

out-of-order designated initialization, nested designated initialization, mixing of designated initializers and regular initializers, and designated initialization of arrays are all supported in the C programming language, but are not allowed in C .

C doesn't have the inheritance concept at all which makes C's version of designating (at least untill C 20) impossible. One possible, future, version would be to designate it "forward" as often done in constructors with delegating constructors. In that case, I'd expect the proper initialization to be this:

Something2 s2 = {
    Something = {
        .Works = false
    },
    .DoesntWorks = true
};

That's however not part of C as of C 20. You can however create constructors in C to accommodate (part of) your needs without designated initializers:

struct Something {
    bool DoesntWork;
};

struct Something2 : public Something {
    Something2(bool Doesnt, bool Does) : 
        Something{Doesnt}, 
        Works{Does} 
    {}
    bool Works;
};

int main() {
    Something2 s2
    {
        true, false
    }; 
}

or initialize each object without user defined constructors at all:

struct Something {
    bool DoesntWork;
};

struct Something2 : public Something {
    bool Works;
};

int main() {
    Something2 s2{
        // You could just make it `{true}` below, but mentioning the
        // subobject fits the purpose of a designated initializer for clarity:
        Something{true},
        // this must however be left unmentioned in C  20 since you can't
        // mix regular initializers with designated ones:
        false
    };
}

CodePudding user response:

This works for me:

struct Something
{
    bool ThisWorks;
};

struct Something2 : Something
{
    bool Works;
};


int main()
{
    Something2 s2 = {
        { .ThisWorks = false },
        .Works = true
    };
}

Online Demo

  • Related