initializer_list中字符串的内容为何为空

Why the content of the string in initializer_list is empty?

本文关键字:list 字符串 initializer      更新时间:2023-10-16

我使用的是map<string,initializer_list<string>>,但我注意到initializer_list<string>包含空字符串,即{"Red","Green","Blue"}将是{"","",""}

通过用vector代替initializer_list,问题将得到解决。

我为什么会有这种行为?

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" ...
}
}

std::initializer_lists通常应仅用作函数参数,或用于循环。请使用适当的容器,如std::vector

你的initializer_list正在悬挂。

initializer_list的工作方式类似于指向临时数组的引用,具有相同的生存期扩展规则:

底层数组是const T[N]类型的临时数组,其中每个元素都是从原始初始值设定项列表的相应元素复制初始化的(除非缩小转换无效(基础数组的生存期与任何其他临时对象相同,只是从数组初始化initializer_list对象会延长数组的生存时间,这与将引用绑定到临时对象完全一样(除了相同的例外,例如初始化非静态类成员(。底层阵列可以在只读存储器中分配。

--cppreference,emphasis mine

如果您将initializer_list创建为一个单独的变量,则寿命扩展将起作用:

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

但在你的情况下,它不起作用,因为:

通常,临时的寿命不能进一步延长";传递它":从临时绑定到的引用初始化的第二个引用不会影响其生存期。

--cppreference

构造std::map<std::string, std::initializer_list<std::string>>的过程涉及到复制/移动initializer_list,因此它不可能工作。