Для статической инициализации, до C ++ 14, нулевая инициализация происходит до постоянной инициализации. Начиная с C ++ 14, постоянная инициализация происходит вместо нулевой инициализации. Инициализация констант в основном происходит для объектов и ссылок, которые инициализируются с помощью константных выражений (или конструкторов constexpr). Подробности здесь .
Компилятору разрешено инициализировать другие статические объекты с использованием постоянной инициализации, если он может гарантировать, что значение будет таким же, как если бы стандартный порядок инициализации былfollow. На практике постоянная инициализация выполняется во время компиляции, а предварительно рассчитанные представления объектов сохраняются как часть образа программы. Если компилятор этого не делает, он все равно должен гарантировать, что эта инициализация произойдет до любой динамической инициализации.
m_myMember
не является статической инициализированной, потому что его конструктор класса не constexpr
. g_myConstant
константа инициализирована. Использование static constexpr
заставляет компилятор инициализировать значение во время компиляции, без constexpr
компилятор может инициализировать во время компиляции. Ваша конструкция четко определена.
Посмотрите этот пример из cppreference :
#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
}
Но теперь, если мы изменим порядок инициализации, он скомпилирует:
#include <iostream>
#include <array>
struct S {
static const int c;
};
//both inits are now constant initialization
const int S::c = 5;
const int d = 10 * S::c;
int main()
{
std::cout << "d = " << d << '\n';
std::array<int, S::c> a1;
std::array<int, d> a2; //now, it's ok
}