无法在向量的向量上emplace_back() 支撑初始值设定项

Cannot emplace_back() a braced initializer on a vector of vectors

提问人:24n8 提问时间:6/7/2019 最后编辑:Nikos C.24n8 更新时间:6/7/2019 访问量:1903

问:

这在某种程度上与我之前提出的关于在对向量上使用的问题有关。emplace_back() 与 push_back 插入 std::vector 时emplace_back

现在我的问题与在向量的向量上使用有关。emplace_back

这是我用评论质疑的代码

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<int>{1,2,3});std::vector<T>::emplace_backpush_back

另外,有人可以解释为什么将大小为 3 的向量插入矩阵中,由 2s 组成?matrix.emplace_back(3,2)

C++ 矢量 STL 回推 emplace

评论

1赞 Jarod42 6/7/2019
matrix.emplace_back(3,2)使用构造函数 。vector(std::size_t size, const T& value)
0赞 24n8 6/7/2019
@jarod42哎呀,完全错过了。

答:

5赞 Nikos C. 6/7/2019 #1

在这种情况下,无法推导到(这是要使用的构造函数所期望的。所以你需要帮助它一点:{1, 2, 3}initializer_list<int>vector<int>

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)

评论

0赞 24n8 6/7/2019
几个后续:(1) 允许将 {1,2,3} 推到 ,它似乎。是否有特殊原因不允许使用此功能?(2) matrix.emplace_back(initializer_list<int>{1, 2, 3}) 与 matrix.emplace_back(vector<int>{1, 2, 3} 有什么不同吗?似乎以这种方式这样做会经历一个向量构造函数,然后是一个initializer_list构造函数,而以你的方式,它只是简单地通过一个initializer_list构造函数。所以似乎你的方式会更有效率?push_backinitializer_list<int>emplace_back
0赞 Nikos C. 6/7/2019
@Iamanon我脑子里没有完整的演绎规则,但我希望我现在能很好地澄清我的答案。