Прямая инициализация
Материал из cppreference.com
Инициализирует объект из явного набора аргументов конструктора.
Содержание |
[править] Синтаксис
T объект ( аргумент );
T объект |
(1) | ||||||||
T объект { аргумент };
|
(2) | (начиная с C++11) | |||||||
T ( другой )
T |
(3) | ||||||||
static_cast< T >( другой )
|
(4) | ||||||||
new T( аргументы, ...)
|
(5) | ||||||||
Класс:: Класс() : элемент( аргументы, ...) { ... }
|
(6) | ||||||||
[ аргумент](){ ... }
|
(7) | (начиная с C++11) | |||||||
[править] Объяснение
Прямая инициализация выполняется в следующих случаях:
1) Инициализация непустым списком выражений в скобках или списками инициализации в фигурных скобках (начиная с C++11).
2) Инициализация объекта неклассового типа с помощью одного инициализатора, заключённого в фигурные скобки (примечание: типы классов и другие варианты использования списка инициализации в фигурных скобках смотрите в разделе инициализация списком) (начиная с C++11).
3) Инициализация prvalue временным объектом (до C++17)результирующего объекта prvalue (начиная с C++17) с помощью приведения в стиле функции или с помощью списка выражений в скобках.
4) Инициализация prvalue временного объекта (до C++17)результирующего объекта prvalue (начиная с C++17) выражением static_cast.
5) Инициализация объекта с динамической длительностью хранения выражением new с инициализатором.
6) Инициализация базового объекта или нестатического элемента списком инициализаторов конструктора.
7) Инициализация элементов объекта замыкания из переменных, захваченных копированием в лямбда-выражении.
Эффекты прямой инициализации:
- Если
T
является типом массива,
|
(до C++20) |
struct A { explicit A(int i = 0) {} }; A a[2](A(1)); // OK: инициализирует a[0] с помощью A(1) и a[1] с помощью A() A b[2]{A(1)}; // ошибка: неявная инициализация списком копирования b[1] // из {} выбранного явного конструктора |
(начиная с C++20) |
- Если
T
является типом класса,
|
(начиная с C++17) |
- проверяются конструкторы
T
, и с помощью разрешения перегрузки выбирается наилучшее совпадение. Затем для инициализации объекта вызывается конструктор.
- проверяются конструкторы
struct B { int a; int&& r; }; int f(); int n = 10; B b1{1, f()}; // OK, продлевается время жизни B b2(1, f()); // верно, но висячая ссылка B b3{1.0, 1}; // ошибка: сужающее преобразование B b4(1.0, 1); // верно, но висячая ссылка B b5(1.0, std::move(n)); // OK |
(начиная с C++20) |
- Иначе, если
T
является неклассовым типом, но исходный тип является классовым, проверяются функции преобразования исходного типа и его базовых классов, если таковые имеются, и путём разрешения перегрузки выбирается наилучшее совпадение. Затем выбранное определяемое пользователем преобразование используется для преобразования выражения инициализатора в инициализируемый объект. - Иначе, если
T
равно bool а исходный тип это