Почему содержимое строки в initializer_list пусто? - PullRequest
0 голосов
/ 13 июля 2020

Я использую map<string,initializer_list<string>>, но я заметил, что initializer_list<string> содержит пустые строки, т.е. {"Red","Green","Blue"} будет {"","",""}.

Заменив initializer_list на vector , проблема будет решена.

Почему у меня такое поведение?

std::map<std::string, std::initializer_list<std::string>> container = { {"Color",{"Red","Green","Blue"}},{"Car",{"BMW","Seat"}} };
for (const auto& item : container) {
    std::cout << item.first << std::endl;
    for (const auto& option : item.second)
    {
        std::cout << option << std::endl; //  option is always "", it should be "Red" or "Green" or "BMW" ...
    }
}

1 Ответ

2 голосов
/ 14 июля 2020

std::initializer_list s обычно следует использовать только как параметры функции или в циклах с заданным диапазоном. Вместо этого используйте правильный контейнер, например std::vector.

Ваши initializer_list болтаются.

initializer_list работают как ссылки, указывающие на временные массивы, с тем же временем жизни extension rules:

Базовый массив - это временный массив типа const T[N], в котором каждый элемент инициализируется копией (за исключением того, что сужающие преобразования недопустимы) из соответствующего элемента исходный список инициализаторов. Время жизни базового массива такое же, как и у любого другого временного объекта, за исключением того, что инициализация объекта initializer_list из массива продлевает время жизни массива точно так же, как привязка ссылки к временному (с тем же исключения, например, для инициализации нестатического c члена класса). Базовый массив может быть выделен в памяти только для чтения.

- cppreference , акцент мой

Если вы создали initializer_list как отдельную переменную, Продление срока жизни будет работать:

std::initializer_list<int> foo = {1, 2, 3};

Но в вашем случае это не сработает, потому что:

В общем, время жизни временного не может быть дополнительно продлено путем «передачи it on ": вторая ссылка, инициализированная из ссылки, к которой был привязан временный объект, не влияет на его время жизни.

- cppreference

Процесс Построение std::map<std::string, std::initializer_list<std::string>> включает в себя копирование / перемещение initializer_list, так что это никак не может работать.

...