为啥initializer_list中的字符串内容为空?

Posted

技术标签:

【中文标题】为啥initializer_list中的字符串内容为空?【英文标题】:Why the content of the string in initializer_list is empty?为什么initializer_list中的字符串内容为空? 【发布时间】:2020-07-13 20:31:21 【问题描述】:

我使用的是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" ...
    

【问题讨论】:

使用 gcc 10.1 x86-64 在 godbolt.org 上运行良好。 通过将initializer_list替换成向量,问题就解决了。 请将该信息添加到问题中,而不是作为评论。 Visual Studio 版本= Visual Studio 2019 版本 16.4,_MSC_VER= 1924 【参考方案1】:

std::initializer_lists 通常只能用作函数参数,或用于 ranged-for 循环。请改用合适的容器,例如 std::vector

你的initializer_lists 悬空。

initializer_lists 的工作方式类似于指向临时数组的引用,具有相同的 lifetime extension 规则:

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

——cppreference,强调我的

如果您将 initializer_list 创建为单独的变量,则生命周期延长将起作用:

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

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

一般来说,临时的生命周期不能通过“传递”来进一步延长:第二个引用,从临时绑定的引用初始化,不会影响它的生命周期。

——cppreference

构造std::map&lt;std::string, std::initializer_list&lt;std::string&gt;&gt;的过程涉及到复制/移动initializer_list,所以它不可能工作。

【讨论】:

以上是关于为啥initializer_list中的字符串内容为空?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 std::initializer_list 不是内置语言?

为啥 std::min(std::initializer_list<T>) 按值接受参数?

为啥具有默认参数 std::initializer_list 的 ctor 不可用(VS2019)?

为啥在使用大括号初始值设定项列表时首选 std::initializer_list 构造函数?

带有 initializer_list 的编译时查找表

lambda 返回 initializer_list 中的奇怪值