Инициализация констант
Устанавливает начальные значения статических переменных до значения константы времени компиляции.
Объяснение
Если статическая или локальная для потока(с C++11) переменная инициализируется константой (см. ниже), выполняется инициализация константой вместо инициализации нулём до всех остальных инициализаций.
Переменная или временный объект obj считается инициализируемой константой, если
- либо у неё есть инициализатор, либо её инициализация по умолчанию приводит к выполнению какой-либо инициализации, и
- её полное выражение инициализации полное выражение является постоянным выражением, за исключением того, что если
objявляется объектом, это полное выражение может также вызывать constexpr конструкторы дляobjи его подобъектов, даже если эти объекты являются типами классов, не являющимися литеральными(с C++11).
Эффекты инициализации константой аналогичны эффектам соответствующей инициализации, за исключением того, что гарантируется, что она завершена до начала любой другой инициализации статического или локального для потока(с C++11) объекта, и она может выполняться во время компиляции.
Примечания
Компилятор может инициализировать другие статические и локальные для потока(с C++11) объекты с помощью инициализации константой, если он может гарантировать, что значение будет таким же, как если бы соблюдалась стандартная последовательность инициализации.
На практике инициализация константой выполняется во время компиляции, и предварительно рассчитанные представления объектов хранятся как часть образа программы (например, в разделе .data). Если переменная является одновременно const и инициализируется константой, её представление объекта может храниться в разделе только для чтения образа программы (например, в разделе .rodata).
Пример
#include <iostream>
#include <array>
struct S
{
static const int c;
};
const int d = 10 * S::c; // not a constant expression: S::c has no preceding
// initializer, this initialization happens after const
const int S::c = 5; // constant initialization, guaranteed to happen first
int main()
{
std::cout << "d = " << d << '\n';
std::array<int, S::c> a1; // OK: S::c is a constant expression
// std::array<int, d> a2; // error: d is not a constant expression
}Вывод:
d = 50
Отчёты об ошибках
Следующие отчёты об ошибках, изменяющие поведение, были применены ретроактивно к ранее опубликованным стандартам C++.
| DR | Применимо к | Поведение, как опубликовано | Корректное поведение |
|---|---|---|---|
| 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 | инициализация по умолчанию не могла быть инициализацией константой (требовались инициализаторы константы) | может |
См. также
-
constexpr - конструктор
- конвертирующий конструктор
- конструктор копирования
- конструктор по умолчанию
-
explicit - инициализация
- конструктор перемещения
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/language/constant_initialization