Aggregate Initialization
An aggregate is one of the following types:
- array type
- class type (typically,
struct
orunion
), that has- no private or protected non-static data members
- no user-declared constructors
- no user-provided, inherited, or explicit constructors
- no user-declared or inherited constructors
- no virtual, private, or protected base classes
- no virtual member functions
- no default member initializers
If we have a struct which has a single integer in it. We would need to do something like initialize the integer class member. If we use the C++03
standard, we must have a constructor for this initialization. The code is as follows.
1 | struct S { |
Now the C++11, we were given the ability to do this uniform initialization syntax. So instead of doing a constructor, we can do this brace initialization syntax. And this works for however many elements you happen to have.
1 | struct S { |
Well, what happens when we introduce class hierarchy here. We have a base class. We get an error if we actually use inheritance from our struct S and that there is no matching constructor for initialization of s
. Because we don’t have any way to initialize the base class.
1 | struct B { |
So what C++17 is giving us is the ability to explicitly specify that we want the base class initialized also.
1 |
|
So we now have with our uniform initialization syntax a way of initializing base class objects
Aggregate Initialization
Aggregate initialization, for example, an array initialize. So we could always initialize like this with a list initialization which is then going to perform aggreagte initialization. So list initialization means you have these braces. In C++20, we can now instead of the braces use parents which is direct initialization.
1 | // aggregate initialization |
Why C++ committee do this? Because you couldn’t really perfect forward aggregates before C++20, that just wasn’t possible. Now you can implement emplace_back so now you can in-place aggregates in C++20. The other thing you can now do which is a little bit more like rare. You couldn’t really do aggregate initialization inside a macro because if you had inside the macro if you have curlies and then you have a comma in there the compiler would think that that’s then the next macro argument after the comma and then the puzzle will just explode. Now you can use parents so that actually compiles and now works since C++20.
1 | struct A { |
Aggregate init inside a macro.
1 | struct A { |
So introduce this feature, we solved two problems.
Narrowing conversions.
1 | struct A { |
Brace elision.
If you have a brace elision like that you have a nested aggregate. So you have an aggregate inside an aggregate. If you do curlys, you get brace solutions so you can basically do the flat right out the flat initializations and it’s going to recurse into the sub aggregates. But the parents doesn’t work.
1 | struct A { |
Lifetime Extension of Temporary Object
You have a reference member, so what list initialization is going to do if you do aggregation via list initialization, it’s going to actually extend the lifetime of the reference if you initialize it with a temporary.
1 | struct A { |
Another case.
If you have a struct A
, which has one aggregation member, and have a non-aggregation member since struct C
has a user-defined constructor. Then if you want to initialize this aggregate with a list initialization by just initialization both of these members. That works with curlys and works with parens.
1 | struct C { |
auto a5 = A{};
is wrong, because you get an implicit initialized aggregate member, and if you do that with curlies, it is going to copy initialize that aggregate member as if by copy initialization from an empty braced init list. And copy initialization doesn’t work with explicit constructors, so you get a compiler error.
auto a6 = A();
is OK. This is actually has a meaning, it has the meaning of value initialization
since C++03, which is going to do zero initialization. This has the same meaning as before, so that’s going to just zero out the struct, and that’s fine.
References
Aggregate Initialization
https://wtffqbpl.github.io/2022/11/13/Aggregate-Initialization/