[2026] C++ Aggregate Initialization | Braces for Structs and Arrays

[2026] C++ Aggregate Initialization | Braces for Structs and Arrays

이 글의 핵심

Aggregates are structs and arrays that meet standard rules; braces initialize members directly. C++20 designated initializers, contrasts with default/value/list init, and API pitfalls.

What is aggregate initialization?

An aggregate is a struct or array (under the standard rules) without user-provided constructors, private/protected non-static data members, virtual functions, etc. You initialize it with a brace list. 아래 코드는 cpp를 사용한 구현 예제입니다. 클래스를 정의하여 데이터와 기능을 캡슐화하며. 코드를 직접 실행해보면서 동작을 확인해보세요.

// 타입 정의
struct Point {
    int x;
    int y;
};
Point p = {10, 20};  // aggregate initialization

Why it matters:

  • Brevity: no ctor boilerplate for plain data
  • Safety: explicit member values
  • Readability: definition and initialization stay aligned 아래 코드는 cpp를 사용한 구현 예제입니다. 클래스를 정의하여 데이터와 기능을 캡슐화하며. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.
// Verbose ctor style
struct Point {
    int x, y;
    Point(int x_, int y_) : x(x_), y(y_) {}
};
Point p(10, 20);
// Aggregate style
struct Point { int x, y; };
Point p = {10, 20};

Aggregate rules (C++17/C++20 oriented)

Roughly, all of the following must hold:

  1. Array or class type (struct/class/union)
  2. No user-provided constructors (compiler-generated defaults OK)
  3. No private/protected non-static data members
  4. No virtual functions
  5. No virtual/private/protected base classes (C++17+: public inheritance allowed) 아래 코드는 cpp를 사용한 구현 예제입니다. 클래스를 정의하여 데이터와 기능을 캡슐화하며. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.
struct Aggregate1 {
    int x;
    double y;
};
struct Aggregate2 : Aggregate1 {
    int z;  // C++17: public base OK
};
struct NonAggregate1 {
    NonAggregate1() = default;  // if user-defined ctor—breaks aggregate in many cases
    // (actual rules depend on edition—check `is_aggregate`)
};

Check at compile time:

#include <type_traits>
struct Point { int x, y; };
static_assert(std::is_aggregate_v<Point>);

Examples

Structs

아래 코드는 cpp를 사용한 구현 예제입니다. 클래스를 정의하여 데이터와 기능을 캡슐화하며. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

struct Person {
    std::string name;
    int age;
    double height;
};
Person p1 = {"Alice", 30, 165.5};
Person p2{"Bob", 25, 175.0};
Person p3 = {"Charlie", 35};   // height value-initialized
Person p4 = {"David"};         // age, height value-initialized

Arrays

아래 코드는 cpp를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

int arr1[5] = {1, 2, 3, 4, 5};
int arr2[5] = {1, 2};  // rest zero
int matrix[2][3] = {
    {1, 2, 3},
    {4, 5, 6}
};

Nested structs

아래 코드는 cpp를 사용한 구현 예제입니다. 클래스를 정의하여 데이터와 기능을 캡슐화하며. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

struct Address {
    std::string city;
    int zipCode;
};
struct Person {
    std::string name;
    Address address;
};
Person p = {
    "Alice",
    {"Seoul", 12345}
};

C++20 designated initializers

아래 코드는 cpp를 사용한 구현 예제입니다. 클래스를 정의하여 데이터와 기능을 캡슐화하며. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

struct Config {
    int width = 800;
    int height = 600;
    bool fullscreen = false;
};
Config cfg = {
    .width = 1920,
    .height = 1080,
    .fullscreen = true
};

Compared to other init forms

SyntaxMeaning (aggregate S)
S a;Default initialization — locals may be indeterminate
S a{};Value initialization — zeros / empty / defaults
S a = {1, 2};Aggregate init (copy-list form)
S a{1, 2};Aggregate + list init
Non-aggregates go through constructors for S a{...}.

C++20 designated initializers (detail)

Use .member = value in declaration order; skipped members are value-initialized. Out-of-order designation is ill-formed in C++ (unlike some C rules). Pros: field names in code; fewer order mistakes.
Caveats: refactoring member order breaks call sites; non-aggregates need ctors instead.

Default member values

Omitted trailing members use default member initializers if present, otherwise value initialization. 아래 코드는 cpp를 사용한 구현 예제입니다. 클래스를 정의하여 데이터와 기능을 캡슐화하며. 코드를 직접 실행해보면서 동작을 확인해보세요.

struct Config {
    int width = 800;
    int height = 600;
    bool fullscreen;  // no default
};
Config c1 = {};                 // all filled per rules
Config c2 = {1920};             // width only

Common issues

Order (designated)

Point p = {.x = 10, .y = 20};  // OK
// Point q = {.y = 20, .x = 10};  // error in C++20

Types with constructors

Non-aggregates cannot use pure {...} aggregate init—use ctors.

Inheritance

struct Base { int x; };
struct Derived : Base { int y; };
Derived d = {{10}, 20};

Array bounds

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

FAQ

Q1: Aggregate conditions?
A: Public members, no user-provided ctor (per rules), no virtuals—see std::is_aggregate. Q2: Partial omission?
A: Yes; remaining members use defaults or value init. Q3: Order?
A: Declaration order; designated init must follow declaration order in C++. Q4: C++20 changes?
A: Designated initializers for aggregates. Related: List initialization, Value initialization, Default initialization. One line: Aggregate initialization fills struct/array members directly with braces—simple and explicit.

Keywords

C++, aggregate initialization, struct, array, designated initializers.

... 996 lines not shown ... Token usage: 63706/1000000; 936294 remaining Start-Sleep -Seconds 3