C++ Aggregates & Aggregate Initialization | Practical Guide

C++ Aggregates & Aggregate Initialization | Practical Guide

이 글의 핵심

Aggregates are simple class types you can brace-initialize without writing constructors—ideal for DTOs when you understand the standard rules and C++20 designated initializers.

Why aggregates matter

Aggregates let you skip constructors for simple “bags of data” and use brace initialization instead.

struct Point {
    int x;
    int y;
};

int main() {
    Point p = {10, 20};
}

Table of contents

  1. Aggregate conditions
  2. Basic syntax
  3. C++17/20 changes
  4. Arrays
  5. Common errors
  6. Production patterns
  7. Full example

1. Aggregate conditions (C++17-style summary)

  • No user-provided constructors (per standard rules—verify with is_aggregate)
  • No private/protected non-static data members
  • No virtual functions
  • No problematic base classes (see standard; public base allowed since C++17)
struct Point { int x, y; };  // aggregate

struct Derived : Point { int z; };  // often aggregate (C++17+)

struct NotAgg {
    virtual void f() {}
    int x;
};

2. Basic syntax

struct Person {
    std::string name;
    int age;
    double height;
};

Person p1 = {"Alice", 30, 165.5};
Person p2 = {"Bob", 25};       // height value-initialized
Person p3 = {};                // all value-initialized
Person p4{"Charlie", 35, 180.0};

3. C++17/20

  • C++17: aggregates may have public base classes.
  • C++20: designated initializers .member = value.
struct Point { int x, y, z; };

Point p = { .x = 10, .y = 20, .z = 30 };

4. Arrays

int arr1[5] = {1, 2, 3, 4, 5};
int arr2[5] = {1, 2};
int arr3[] = {1, 2, 3};

int matrix[2][3] = { {1,2,3}, {4,5,6} };

5. Common errors

  • User-defined ctor → no longer aggregate brace list in the same way.
  • Private members break aggregate rules.
  • Too many initializers for members.

6. Production patterns

Configuration

struct DatabaseConfig {
    std::string host = "localhost";
    int port = 5432;
    std::string database = "mydb";
};

DatabaseConfig prod = {
    .host = "prod.example.com",
    .port = 5432,
    .database = "production"
};

Test tables

struct TestData {
    int input;
    int expected;
    std::string description;
};

std::vector<TestData> cases = {
    {0, 0, "zero"},
    {5, 25, "five squared"}
};

Summary

ConceptMeaning
AggregateSimple type per standard rules
InitUsually { ... }
C++17Bases allowed
C++20Designated initializers

Related: Initialization order.


FAQ

Q: Aggregate vs POD?
A: POD is stricter (trivial + aggregate-related rules). Aggregate is broader.

Q: Partial init?
A: Remaining members value-initialized or use member defaults.

Resources: cppreference — Aggregate initialization.


  • C++ Uniform initialization
  • C++ Value initialization
  • C++ Designated initializer

Keywords

C++, aggregate, aggregate initialization, struct, POD, C++20.


  • C++ Aggregate initialization
  • C++ struct vs class