Что такое Uniform initialization? Aggregate initialization?cplus-94

Uniform Initialization

Введена в C++11 для унификации синтаксиса инициализации. Использует фигурные скобки {}.

Основные особенности:

int x{5};                // Вместо int x = 5;
std::vector<int> v{1, 2, 3}; // Инициализация списком

Преимущества:

  1. Единый синтаксис для всех типов
  2. Запрещает сужающие преобразования (narrowing conversions)
    int y{7.5}; // Ошибка: narrowing conversion
    
  3. Избегает most vexing parse
    Widget w{};    // Явный вызов конструктора по умолчанию
    Widget w();    // Объявление функции!
    

Aggregate Initialization

Специальный вид инициализации для агрегатных типов.

Что такое агрегат?

Тип является агрегатом, если:

  1. Нет пользовательских конструкторов
  2. Нет private/protected не-static членов
  3. Нет базовых классов
  4. Нет виртуальных функций

Синтаксис:

struct Point {
    int x;
    int y;
};

Point p{1, 2};  // Aggregate initialization

Особенности:

  1. Инициализация в порядке объявления членов
  2. Можно пропускать элементы (они будут value-initialized)
    int arr[5]{1, 2}; // arr = {1, 2, 0, 0, 0}
    
  3. Работает с массивами и структурами

Различия между Uniform и Aggregate

ХарактеристикаUniform InitializationAggregate Initialization
ПрименимостьЛюбые типыТолько агрегатные типы
Синтаксис{}{}
ПорядокЗависит от конструктораПорядок объявления членов
Сужение типовЗапрещеноРазрешено в C (но не в C++)

Примеры использования

Uniform initialization с классами

class Widget {
    int x;
    double y;
public:
    Widget(int a, double b) : x{a}, y{b} {}
};

Widget w{10, 3.14};  // Вызов конструктора

Aggregate initialization

struct RGB {
    uint8_t r;
    uint8_t g;
    uint8_t b;
};

RGB white{255, 255, 255};  // Инициализация агрегата

Нововведения C++20

  1. Designated Initializers (позаимствовано из C99):
    RGB red{.r = 255, .g = 0, .b = 0};  // Явное указание членов
    
  2. Разрешение агрегатной инициализации с наследованием

Резюмируем

  1. Uniform Initialization ({}):

    • Универсальный синтаксис для всех типов
    • Безопаснее традиционных способов инициализации
    • Предотвращает narrowing conversions
  2. Aggregate Initialization:

    • Специальный случай для простых структур и массивов
    • Инициализация в порядке объявления членов
    • Не требует конструкторов

Рекомендация: в современном C++ предпочитайте uniform initialization ({}) как более безопасный и универсальный способ инициализации объектов.