If I don't define a constructor in a struct, I can initialize it by just picking a certain value like this:
struct Foo {
int x, y;
};
Foo foo = {.y = 1};
But if I add new default constructor then I lose this feature:
struct Bar {
int x, y;
Bar(int value) : x(value), y(value) {}
};
Bar bar1 = 1;
Bar bar2 = {.y = 2}; // error: a designator cannot be used with a non-aggregate type "Bar"
Is it possible to have both ways?
I tried adding the default constructor Bar () {}
but it seems to not work either.
You can't have your cake and eat it too. If the object has a constructor it is no longer an aggregate, and only aggregates can be initialized with designated initializers. You can't use constructors for arbitrary initialization logic with aggregates.
Are we toasted though? No, because there's the "named constructor" idiom. It's essentially just a static member function that returns an initialized object, and able to perform some logic. The idiom is compatible with aggregate initialization.
struct Foo {
int x, y;
static Foo filled_with(int value) {
return {.x = value, .y = value};
}
};
Foo foo = {.y = 1}; // Still an aggregate.
Foo foo2 = Foo::filled_with(2); // Custom logic
There's not even any copying or moving with this approach, because C++17 removed the possibility for those. foo2
is initialized directly with whatever the static member does.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With