Агрегатная инициализация
Материал из cppreference.com
Инициализирует агрегат из списка инициализаторов. Это форма инициализации списком. (начиная с C++11)
Синтаксис
T объект = { арг1, арг2, ... };
|
(1) | ||||||||
T объект { арг1, арг2, ... };
|
(2) | (начиная с C++11) | |||||||
T объект = { .назн1 = арг1 , .назн2 { арг2 } ... };
|
(3) | (начиная с C++20) | |||||||
T объект { .назн1 = арг1 , .назн2 { арг2 } ... };
|
(4) | (начиная с C++20) | |||||||
1,2) Инициализация агрегата обычным списком инициализаторов.
3,4) Инициализация агрегата назначенными инициализаторами (только классовый агрегата).
Объяснение
Определения
Агрегат относится к одному из следующих типов:
- тип массива
- классовый тип (обычно
structилиunion), который имеет
|
(до C++11) |
|
(начиная с C++11) (до C++20) |
|
(начиная с C++20) |
- нет закрытых или защищённых прямых (начиная с C++17) нестатических элементов данных
|
(до C++17) |
|
(начиная с C++17) |
- нет виртуальных функций-элементов
| (начиная с C++11) (до C++14) |
Элементами агрегата являются:
- для массива это элементы массива в порядке возрастания индекса или
|
(до C++17) |
|
(начиная с C++17) |
Процесс
Эффекты агрегатной инициализации:
1) Отклоняются следующие ошибочные случаи:
- количество предложений инициализатора в списке инициализаторов превышает количество элементов агрегата, или
- инициализируется массив неизвестной привязки с пустым списком инициализаторов (
{}).
char cv[4] = {'a', 's', 'd', 'f', 0}; // ошибка
int x[] = {} // ошибка
2) Явно инициализированные элементы агрегата определяются следующим образом:
|
(начиная с C++20) |
- Иначе, если список инициализаторов не пуст, явно инициализированные элементы агрегата являются первыми n элементами агрегата, где n количество элементов в списке инициализаторов.
- Иначе список инициализаторов должен быть пустым (
{}) и не иметь явно инициализированных элементов.
- Программа некорректа, если агрегат является объединением и имеется два или более явно инициализированных элемента:
union u { int a; const char* b; };
u a = {1}; // OK: явно инициализируется элемент `a`
u b = {0, "asdf"}; // ошибка: явно инициализируется два элемента
u c = {"asdf"}; // ошибка: int не может быть инициализирован "asdf"
// списки назначенных инициализаторов C++20
u d = {.b = "asdf"}; // OK: может явно инициализировать неначальный элемент
u e = {.a = 1, .b = "asdf"}; // ошибка: явно инициализируется два элемента
3) Инициализируется каждый элемент агрегата в порядке элементов. То есть все вычисления значений и побочные эффекты, связанные с данным элементом, выполняются до вычислений любого элемента, следующего за ним по порядку (начиная с C++11).
Инициализация элементов
Для каждого явно инициализированного элемента:
struct C
{
union
{
int a;
const |