What Are Aggregates and Pods and How/Why Are They Special

Advantages of aggregate classes over regular classes [duplicate]

What are the advantages <...> of aggregates

Unlike "usual" classes, aggregate types:

  1. have pre-defined "constructor" (your example)
  2. need no tuple-like interface boilerplate for structured bindings:
struct { int field1, field2; } aggregate;
auto&& [_1, _2] = aggregate;

  1. 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



Leave a reply



Submit