Complete Guide to C++ Aggregate Initialization
이 글의 핵심
C++ aggregates: brace-initialization for structs and arrays without user-defined constructors. POD, C++17 base classes, C++20 designated initializers.
What is Aggregate Initialization? Why is it important?
Problem Scenario: Do simple structs need constructors?
Problem: Writing constructors for simple structs that only hold data increases boilerplate code.
struct Point {
int x;
int y;
// Do we need a constructor?
Point(int x, int y) : x(x), y(y) {}
};
int main() {
Point p(10, 20);
}
Solution: Aggregate types can be created easily with brace initialization without constructors.
struct Point {
int x;
int y;
// No constructor needed
};
int main() {
Point p = {10, 20}; // Simple!
}
Table of Contents
- Conditions for Aggregate Types
- Basic Initialization Syntax
- Changes in C++17/20
- Array Initialization
- Common Errors and Solutions
- Production Patterns
- Complete Example
1. Conditions for Aggregate Types
C++17 Aggregate Conditions
- Arrays, or
- Classes/structs:
- No user-defined constructors (default/delete is OK)
- No private/protected non-static members
- No virtual functions
- No virtual/private/protected base classes
// ✅ Aggregate
struct Point {
int x;
int y;
};
// ✅ Aggregate (C++17+, base classes are OK)
struct Base {
int a;
};
struct Derived : Base {
int b;
};
// ❌ Not Aggregate (constructor exists)
struct NotAgg1 {
NotAgg1(int x) : value(x) {}
int value;
};
// ❌ Not Aggregate (private member exists)
struct NotAgg2 {
private:
int x;
public:
int y;
};
// ❌ Not Aggregate (virtual function exists)
struct NotAgg3 {
virtual void func() {}
int x;
};
Type Checking
#include <type_traits>
struct Agg { int x, y; };
struct NotAgg { NotAgg(int x) : value(x) {} int value; };
int main() {
static_assert(std::is_aggregate_v<Agg>); // true
static_assert(!std::is_aggregate_v<NotAgg>); // true
}
2. Basic Initialization Syntax
Struct Initialization
struct Person {
std::string name;
int age;
double height;
};
int main() {
// Initialize all members
Person p1 = {"Alice", 30, 165.5};
// Initialize some members (others get default values)
Person p2 = {"Bob", 25}; // height = 0.0
// Empty initialization
Person p3 = {}; // name = "", age = 0, height = 0.0
// C++11 uniform initialization
Person p4{"Charlie", 35, 180.0};
}
Nested Structs
struct Address {
std::string city;
int zipcode;
};
struct Employee {
std::string name;
int id;
Address address;
};
int main() {
Employee emp = {
"Alice",
100,
{"Seoul", 12345}
};
std::cout << emp.address.city << '\n'; // Seoul
}
3. Changes in C++17/20
C++17: Base Classes Allowed
struct Base {
int a;
};
struct Derived : Base {
int b;
};
int main() {
// C++17+: Base classes are allowed in Aggregates
Derived d = {{10}, 20}; // a = 10, b = 20
}
C++20: Designated Initializers
struct Point {
int x;
int y;
int z;
};
int main() {
// C++20: Specify member names
Point p = {
.x = 10,
.y = 20,
.z = 30
};
}
4. Array Initialization
1D Arrays
int arr1[5] = {1, 2, 3, 4, 5};
int arr2[5] = {1, 2}; // {1, 2, 0, 0, 0}
int arr3[] = {1, 2, 3}; // Size auto-detected (3)
2D Arrays
int matrix[2][3] = {
{1, 2, 3},
{4, 5, 6}
};
// Flattened initialization
int matrix2[2][3] = {1, 2, 3, 4, 5, 6};
Struct Arrays
struct Point { int x, y; };
Point points[3] = {
{0, 0},
{10, 20},
{30, 40}
};
// C++20 Designated Initializers
Point points2[2] = {
{.x = 0, .y = 0},
{.x = 10, .y = 20}
};
5. Common Errors and Solutions
Error 1: Classes with Constructors
Symptom: error: no matching constructor.
// ❌ Constructor exists
struct NotAggregate {
NotAggregate(int x) : value(x) {}
int value;
};
// NotAggregate obj = {10}; // Error
// ✅ No constructor
struct Aggregate {
int value;
};
Aggregate obj = {10}; // OK
Error 2: Private Members
// ❌ Private member exists
struct NotAggregate {
private:
int x;
public:
int y;
};
// NotAggregate obj = {1, 2}; // Error
// ✅ All members are public
struct Aggregate {
int x;
int y;
};
Aggregate obj = {1, 2}; // OK
Error 3: Exceeding Member Count
struct Point {
int x;
int y;
};
int main() {
Point p1 = {1, 2}; // OK
// Point p2 = {1, 2, 3}; // Error: 2 members but 3 values provided
}
Error 4: Inheritance and Aggregates
struct Base {
int a;
};
// ✅ Public inheritance
struct Derived1 : Base {
int b;
};
Derived1 d1 = {{10}, 20}; // OK
// ❌ Private inheritance
struct Derived2 : private Base {
int b;
};
// Derived2 d2 = {{10}, 20}; // Error
6. Production Patterns
Pattern 1: Configuration Structs
struct DatabaseConfig {
std::string host = "localhost";
int port = 5432;
std::string database = "mydb";
std::string user = "admin";
std::string password;
int connection_pool_size = 10;
};
DatabaseConfig prod_config = {
.host = "prod.example.com",
.port = 5432,
.database = "production",
.user = "app_user",
.password = "secret",
.connection_pool_size = 100
};
Pattern 2: Test Fixtures
struct TestData {
int input;
int expected;
std::string description;
};
std::vector<TestData> test_cases = {
{0, 0, "zero"},
{1, 1, "one"},
{5, 25, "five squared"},
{-3, 9, "negative squared"}
};
for (const auto& test : test_cases) {
int result = square(test.input);
assert(result == test.expected);
}
Summary
| Concept | Description |
|---|---|
| Aggregate | Simple types without constructors |
| Initialization | Use braces {} |
| Conditions | No constructors, public members, no virtual functions |
| C++17 | Base classes allowed |
| C++20 | Designated Initializers added |
Aggregate Initialization is a fundamental feature of C++ for initializing simple data structures without boilerplate.
FAQ
Q1: What is an Aggregate?
A: A simple type without constructors, with all members being public. Examples include arrays and structs.
Q2: How is it different from POD?
A: POD (Plain Old Data) is an Aggregate type that also meets trivial conditions. Aggregate is a broader concept.
Q3: What happens if only some members are initialized?
A: Remaining members are initialized to default values or 0.
Q4: What changed in C++17?
A: Starting from C++17, base classes can be part of Aggregate types.
Q5: What changed in C++20?
A: Designated Initializers were introduced, allowing initialization by specifying member names.
Q6: Where can I learn more about Aggregates?
A:
- cppreference - Aggregate initialization
- “C++ Primer” by Stanley Lippman
- “Effective C++” by Scott Meyers
One-liner summary: Aggregate Initialization allows you to initialize simple structs without boilerplate. Next, check out Initialization Order for more insights.