【问题标题】:Cannot emplace_back() a braced initializer on a vector of vectors不能 emplace_back() 向量向量上的大括号初始值设定项
【发布时间】:2019-10-22 07:53:18
【问题描述】:

这与我之前提出的关于在对向量上使用emplace_back 的问题有些相关。 emplace_back() vs push_back when inserting a pair into std::vector

现在我的问题是关于在向量向量上使用emplace_back

这是我对 cme​​ts 提出质疑的代码

std::vector<std::vector<int>> matrix;

matrix.emplace_back({1,2,3}); //doesn't compile

matrix.emplace_back(1,2,3); //doesn't compile

matrix.push_back({1,2,3}); //works and does what is expected (insert a vector made of {1,2,3} into matrix);

matrix.emplace_back(std::vector<int>{1,2,3});   //works but 
//defeats the purpose of using emplace_back since this makes a copy
//and is thus equivalent to push_back in this case?

matrix.emplace_back(3,2) //this compiles, 
//but it seems to insert a vector of size 3 made of 2s into the matrix. 
//not actually sure why it does this

因此,由此看来,matrix.emplace_back(std::vector&lt;int&gt;{1,2,3}); 似乎是在向量向量上使用std::vector&lt;T&gt;::emplace_back 的唯一正确方法,但这似乎与push_back 相比没有任何优势。我对这个问题的理解正确吗?

另外,有人能解释一下为什么matrix.emplace_back(3,2) 在矩阵中插入一个由 2 组成的大小为 3 的向量吗?

【问题讨论】:

  • matrix.emplace_back(3,2) 使用构造函数vector(std::size_t size, const T&amp; value)
  • @jarod42 糟糕,完全错过了。

标签: c++ vector stl push-back emplace


【解决方案1】:

在这种情况下,{1, 2, 3} 不能推导出为 initializer_list&lt;int&gt;(这是您要使用的 vector&lt;int&gt; 构造函数所期望的。)所以您需要帮助它一点:

matrix.emplace_back(initializer_list<int>{1, 2, 3});

使用push_back() 时不需要这样做。我不知道确切的细节,但emplace_back() 是一个函数模板,而push_back() 不是。模板的推导规则是不同的(方式更严格。)并且大括号初始值设定项没有类型。因此,它对类型推导的工作方式有自己的特殊规则。

至于效率,这个:

matrix.emplace_back(vector<int>{1, 2, 3});

构造两个向量。 matrix 中的空向量,以及传递的临时向量。临时被移动到空向量中。所以真的没那么糟糕。

但是,这个:

matrix.emplace_back(initializer_list<int>{1, 2, 3});

使用接受 initializer_list 的构造函数只构造一个向量。请注意,这里没有创建“额外的”initializer_list 对象。在使用大括号初始化创建任何向量时,无论如何都会创建这样的对象:

vector<int> vec{1, 2, 3};

这也创建了一个initializer_list 对象,因为这是向量构造函数所采用的。

至于emplace_back(2,3)为什么起作用,那是因为有一个向量构造函数,它接受一个大小和一个值。

【讨论】:

  • 一些后续行动:(1)push_back 允许将 {1,2,3} 扣除到initializer_list&lt;int&gt;,它出现了。 emplace_back 不允许此功能是否有特殊原因? (2) matrix.emplace_back(initializer_list{1, 2, 3}) 是否与 matrix.emplace_back(vector{1, 2, 3}) 不同。这样做似乎是通过一个向量构造函数,然后是一个 initializer_list 构造函数,而以你的方式它只是简单地通过一个 initializer_list 构造函数。所以看起来你的方式会稍微更有效率?
  • @Iamanon 我脑子里没有完整的演绎规则,但我希望我现在已经足够清楚我的答案了。
猜你喜欢
  • 2015-08-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-31
  • 2013-08-23
  • 1970-01-01
  • 1970-01-01
  • 2021-12-03
  • 1970-01-01
相关资源
最近更新 更多