Пространства имён
Варианты
Действия

Константная инициализация

Материал из cppreference.com
< cpp‎ | language
 
 
 
 

Устанавливает начальные значения статических переменных в константу времени компиляции.

Содержание

[править]Синтаксис

staticT&ссылка= constexpr; (1)
staticTобъект= constexpr; (2)

[править]Объяснение

Константная инициализация выполняется вместо инициализации нулём статических и локальных к потоку(начиная с C++11) объектов и перед всеми другими инициализациями. Только следующие переменные инициализируются константами:

1) Статические или локальные к потоку(начиная с C++11) ссылки, если они привязаны к статическому значению lvalue(до C++11)glvalue(начиная с C++11), к временному объекту (или его подобъекту)(начиная с C++11) или к функции, и если каждое выражение (включая неявные преобразования) в инициализаторе ссылки представляет собой константное выражение.
2) Статический или локальный к потоку(начиная с C++11) объектPODType(до C++11) (не обязательно классового типа), который не инициализируется вызовом конструктора, если объект инициализируется значением или если каждое выражение в его инициализаторе является константным выражением.
3) Статический или локальный к потоку объект классового типа, который инициализируется вызовом конструктора, если конструктор является constexpr и все аргументы конструктора (включая неявные преобразования) являются константными выражениями, и если инициализаторы в списке инициализаторов конструктора и инициализаторы в фигурных скобках или равенства элементов класса содержат только константные выражения.
(начиная с C++11)

Эффекты константной инициализации такие же, как эффекты соответствующей инициализации, за исключением того, что гарантируется, что она будет завершена до любой другой инициализации статического или локального к потоку(начиная с C++11) объекта, и она может быть выполнена во время компиляции.

[править]Примечание

Компилятору разрешается инициализировать другие статические и локальные к потоку(начиная с C++11) объекты, используя константную инициализацию, если она может гарантировать, что значение будет таким же, как если бы следовал стандартный порядок инициализации.

На практике константная инициализация выполняется во время компиляции, а предварительно вычисленные представления объектов сохраняются как часть образа программы (например, в разделе .data). Если переменная инициализирована как const, так и константой инициализацией, её объектное представление может быть сохранено в разделе образа программы, доступном только для чтения (например, в разделе .rodata).

[править]Пример

#include <iostream>#include <array>   struct S {staticconstint c;};   constint d =10* S::c;// неконстантное выражение: S::c не имеет предшествующего// инициализатора, её инициализация происходит после constconstint S::c=5;// константная инициализация, которая гарантированно// произойдёт первой   int main(){std::cout<<"d = "<< d <<'\n';std::array<int, S::c> a1;// OK: S::c константное выражение// std::array<int, d> a2; // ошибка: d не является константным выражением}

Вывод:

d = 50

[править]Отчёты о дефектах

Следующие изменения поведения были применены с обратной силой к ранее опубликованным стандартам C++:

Номер Применён Поведение в стандарте Корректное поведение
CWG 441 C++98 ссылки не могут быть инициализированы константно сделаны константно инициализируемыми
CWG 1489 C++98 было неясно, может ли инициализация значением объекта
быть константной инициализацией
может
CWG 1747 C++98 привязка ссылки к функции не может быть константной
инициализацией
может
CWG 1834 C++11 привязка ссылки к xvalue не может быть константной
инициализацией
может
CWG 2026 C++98 было указано, что инициализация нулём всегда происходит
первой, даже до константной инициализации
нет инициализации нулём, если применяется
константная инициализация
CWG 2366 C++98 инициализация по умолчанию не могла быть константной
инициализацией (требовались константные инициализаторы)
может

[править]Смотрите также

close