为啥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_list
s 通常只能用作函数参数,或用于 ranged-for 循环。请改用合适的容器,例如 std::vector
。
你的initializer_list
s 悬空。
initializer_list
s 的工作方式类似于指向临时数组的引用,具有相同的 lifetime extension 规则:
底层数组是一个
const T[N]
类型的临时数组,其中每个元素都是从原始初始化器列表的相应元素复制初始化的(除了缩小转换无效)。 底层数组的生命周期与任何其他临时对象相同,只是从数组初始化initializer_list
对象会延长数组的生命周期,这与将引用绑定到临时对象(使用相同的例外,例如用于初始化非静态类成员)。底层数组可以分配在只读内存中。——cppreference,强调我的
如果您将 initializer_list
创建为单独的变量,则生命周期延长将起作用:
std::initializer_list<int> foo = 1, 2, 3;
但在你的情况下它不起作用,因为:
一般来说,临时的生命周期不能通过“传递”来进一步延长:第二个引用,从临时绑定的引用初始化,不会影响它的生命周期。
——cppreference
构造std::map<std::string, std::initializer_list<std::string>>
的过程涉及到复制/移动initializer_list
,所以它不可能工作。
【讨论】:
以上是关于为啥initializer_list中的字符串内容为空?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 std::initializer_list 不是内置语言?
为啥 std::min(std::initializer_list<T>) 按值接受参数?
为啥具有默认参数 std::initializer_list 的 ctor 不可用(VS2019)?