In my use case I needed to initialize a class variable using an initializer list. I learnt that an aggregate class is a class that just has user defined data members in it.
The advantage of aggregate is that we can use initializer list like this
struct fileJobPair {
int file;
int job;
};
fileJobPair obj = {10, 20};
But if I add a constructor to it, the class no longer remains an aggregate
struct fileJobPair {
int file;
int job;
fileJobPair() {
file = job = 0;
}
fileJobPair(int a, int b) {
file = a;
job = b;
}
};
But I see that the initializer list advantage that we had for aggregate classes can still be used over here.
fileJobPair obj = {10, 20};
So my question is why do we even need an aggregate if the same thing can be acieved by regular class. What are the advantages and real life use case of aggregates.
What are the advantages <...> of aggregates
Unlike "usual" classes, aggregate types:
struct { int field1, field2; } aggregate;
auto&& [_1, _2] = aggregate;
Aggregate{.something = 42, .something_else = "whatever"};
Maybe there's something else I didn't think about.
What are the <...> real life use case of aggregates
E.g. you can (de)serialize them with no boilerplate thanks to #2, see also Boost.PFR. You can easily merge them (like tuples), "foreach" their fields etc.
An example for #3: replace tons of the Builder pattern code with
struct Foo {
struct Builder { std::string_view a, b, c; };
constexpr Foo(Builder); // TODO
} example{{.a = "cannot set a field twice", .c = "can skip fields"}};
the same thing can be acieved by regular class
As you can see, it either cannot or requires extra boilerplate.