[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:
- Array or class type (struct/class/union)
- No user-provided constructors (compiler-generated defaults OK)
- No private/protected non-static data members
- No virtual functions
- 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
| Syntax | Meaning (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.
Related posts
- C++ List initialization
- C++ Value initialization
- C++ Designated initializers
- C++ Default initialization