无法在vector的向量上使用emplace_back()大括号的初始化程序

时间:2019-06-06 19:01:52

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

这与我先前问过的关于在成对向量上使用emplace_back的问题有关。 emplace_back() vs push_back when inserting a pair into std::vector

现在我的问题是关于在向量的向量上使用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_back的唯一正确方法,但这似乎没有push_back的优势。我对此事的理解正确吗?

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

1 个答案:

答案 0 :(得分:3)

在这种情况下,不能将{1, 2, 3}推导为initializer_list<int>(这就是您要使用的vector<int>构造函数所期望的。)因此,您需要一点帮助: / p>

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)起作用的原因,是因为有一个向量构造器需要一个大小和一个值。