【问题标题】: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

标签: c++ c++11 c++14


【解决方案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,所以它不可能工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-31
    • 1970-01-01
    • 1970-01-01
    • 2012-03-17
    相关资源
    最近更新 更多