Advantages of aggregate classes over regular classes [duplicate]
What are the advantages <...> of aggregates
Unlike "usual" classes, aggregate types:
- have pre-defined "constructor" (your example)
- need no tuple-like interface boilerplate for structured bindings:
struct { int field1, field2; } aggregate;
auto&& [_1, _2] = aggregate;
- have designated initializers:
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.
Why is std::is_aggregateT an aggregate?
However, aggregate classes must not have a base class by definition
This is no longer true. [dcl.init.aggr]/1 defines an aggregate as
An aggregate is an array or a class with
no user-provided, explicit, or inherited constructors ([class.ctor]),
no private or protected non-static data members (Clause [class.access]),
no virtual functions, and
no virtual, private, or protected base classes ([class.mi]).
[ Note: Aggregate initialization does not allow accessing protected and private base class' members or constructors. — end note ]
There is no longer a condition that it does not have a base class like it did in C++14 and earlier. As long as it has a public, non virtual base class that is now allowed. This means that the type traits are now considered aggregates as long as the above holds true for them
Why does inheriting constructors break aggregate initialization? [duplicate]
Since C++17, aggregates can have base classes, so that for such structures being derived from other classes/structures list initialization is allowed:
struct MoreData : Data {
bool done;
};
MoreData y{{"test1", 6.778}, false};
In C++17 an aggregate is defined as
- either an array
- or a class type (class, struct, or union) with:
- no user-declared or explicit constructor
- no constructor inherited by a using declaration
- no private or protected non-static data members
- no virtual functions
- no virtual, private, or protected base classes
For more details you can refer to Chapter 4 Aggregate Extensions from C++17 - The Complete Guide By Nicolai M. Josuttis
What are POD types in C++?
POD stands for Plain Old Data - that is, a class (whether defined with the keyword struct
or the keyword class
) without constructors, destructors and virtual members functions. Wikipedia's article on POD goes into a bit more detail and defines it as:
A Plain Old Data Structure in C++ is an aggregate class that contains only PODS as members, has no user-defined destructor, no user-defined copy assignment operator, and no nonstatic members of pointer-to-member type.
Greater detail can be found in this answer for C++98/03. C++11 changed the rules surrounding POD, relaxing them greatly, thus necessitating a follow-up answer here.
What caused the following aggregate initialization problem?
You must set your language version to C++20 for designated initializers to work. On visual studio you must enable the flag /std:c++latest
and -std=c++20
on other compilers
Related Topics
Setting Timeout for C/C++ Function Call
Resolve Build Errors Due to Circular Dependency Amongst Classes
Why Do I Have to Access Template Base Class Members Through the This Pointer
When Does Invoking a Member Function on a Null Instance Result in Undefined Behavior
How to Add Reflection to a C++ Application
How to Call a Constructor from Another Constructor (Do Constructor Chaining) in C++
Why Can't C++ Be Parsed With a Lr(1) Parser
What Does T&& (Double Ampersand) Mean in C++11
Automatically Add All Files in a Folder to a Target Using Cmake
What Are the Differences Between a Pointer Variable and a Reference Variable
What Are Aggregates and Pods and How/Why Are They Special
Difference Between Public, Private, and Protected Inheritance in C++
Output Unicode Strings in Windows Console App
What Do the Following Phrases Mean in C++: Zero-, Default- and Value-Initialization
How to Convert a Std::String to Int
Conditions For Automatic Generation of Default/Copy/Move Ctor and Copy/Move Assignment Operator