глобальный порядок инициализации с constexpr - PullRequest
6 голосов
/ 06 октября 2019

Давайте рассмотрим этот кусок кода, который просто пытается инициализировать карту из массива constexpr:

#include <string>
#include <map>
#include <array>
#include <tuple>

constexpr std::array<std::pair<int, const char *>, 10> my_array {
    { { 0, "dd" },
    { 1, "dd" },
    { 2, "dd" },
    { 7, "dd" },
    { 8, "dd" },
    { 9, "dd" }}
   };

std::map<int, std::string> my_map(std::begin(my_array), std::end(my_array));

int main() {
    return my_map[0].size(); //dummy random operation
}

Я знаю, что нет способа предсказать порядок инициализации для двух переменных (my_array и my_map). Тем не менее, my_array - это constexpr, поэтому он должен быть доступен во время компиляции, поэтому при запуске не должно быть проблем с «порядком инициализации».

Правильно ли этот код или проблема с порядком инициализации остается?

1 Ответ

3 голосов
/ 06 октября 2019

[basic.start.static / 2] :

Постоянная инициализация выполняется, если переменная или временный объект со статической или длительностью хранения потока инициализируется постоянной. [...] Вместе, нулевая инициализация и постоянная инициализация называются статической инициализацией;все остальные инициализации - это динамическая инициализация. Вся статическая инициализация настоятельно происходит до ([intro.races]) любой динамической инициализации .

Итак, «Правильно ли этот код?»: Да, поскольку my_array является константойинициализируется, и это происходит до динамической инициализации (my_map).

(Эта цитата взята из текущего проекта стандарта, но это правило существует и для C ++ 14)

...