这与我先前问过的关于在成对向量上使用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的向量插入矩阵吗?
答案 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)
起作用的原因,是因为有一个向量构造器需要一个大小和一个值。