使用初始化列表作为值时插入 std::list<std::vector<int>> 失败?

Posted

技术标签:

【中文标题】使用初始化列表作为值时插入 std::list<std::vector<int>> 失败?【英文标题】:Insertion to std::list<std::vector<int>> failed when using initializer list as the value? 【发布时间】:2020-06-24 14:06:20 【问题描述】:

我有一个如下所示的 C++ sn-p:

  std::list<std::vector<int>> lv;
  lv.push_back();
  std::cout << lv.size() << std::endl; // "1"

  lv.insert(lv.end(), );  // Oops!
  // lv.insert(lv.end(), std::vector<int>());  // OK
  std::cout << lv.size() << std::endl; // Still got "1", but why?

如您所见,当使用 创建默认std::vector&lt;int&gt; 时,插入根本没有发生。虽然我知道在使用 C++ 的初始化列表时有很多微妙之处,但我想知道这个示例中的问题是什么?

谢谢!

【问题讨论】:

我假设您已经想通了,但一种解决方法是 lv.insert(lv.end(), ); 是的,我错过了文档中的最后一个重载。谢谢! 【参考方案1】:

重载分辨率

lv.insert(lv.end(), );  // Oops!

调用将解析(正式地,根据[over.ics.rank]/3.1 选择为最佳可行函数)到以下std::list&lt;&gt;::insert 重载[摘自std::list&lt;&gt;::insert at cppreference,强调我的]:

iterator insert( const_iterator pos, std::initializer_list<T> ilist );

从初始化列表中插入元素 ilist 在 pos 之前。

但是由于初始化列表是空的,没有元素来自要插入。


您同样可以在列表初始化中使用嵌套列表初始化调用相同的 insert 重载,

lv.insert(lv.end(), );  // Size is now 2.

这样最里面的列表初始化将解析为(根据[over.match.list]/1)std::initializer_list constructor of std::vector

vector( std::initializer_list<T> init,
        const Allocator& alloc = Allocator() );

因此,将std::vector&lt;int&gt; 类型的单个元素(特别是一个空的此类向量)插入到std::list&lt;std::vector&lt;int&gt;&gt; 对象中。

【讨论】:

【参考方案2】:

当您调用push_back 时, 参数被推断为列表的元素类型,因此单个vector 被插入到列表中。

当您调用insert 时,您正在使用初始化器列表重载,并且由于初始化器列表为空,因此不会将任何元素添加到列表中。

【讨论】:

以上是关于使用初始化列表作为值时插入 std::list<std::vector<int>> 失败?的主要内容,如果未能解决你的问题,请参考以下文章

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

C ++ std :: list分段错误[重复]

是否应弃用 std::list ?

在基于范围的 for 循环期间插入 std::list 的后面

列表初始化使用啥构造函数

std::list