我有一个std::vector<std::vector<double>>
,并想在最后添加一些元素,所以这是我的试用版:
std::vector<std::vector<double> > vec;
vec.emplace_back({0,0});
但是这不会编译,而以下将会这样做:
std::vector<double> vector({0,0});
为什么emplace_back不能在这个位置构建元素?或者我做错了什么?
感谢您的帮助。
答案 0 :(得分:16)
前面的回答提到,当你在行中构造向量并安置它时,你可以得到编译代码。
但是,这意味着您在临时向量上调用move-constructor,这意味着您不是就地构造向量,而这是使用emplace_back
而不是{{push_back
的全部原因。 1}}。
相反,您应该将初始化列表转换为initializer_list
,如下所示:
#include <vector>
#include <initializer_list>
int main()
{
std::vector<std::vector<int>> vec;
vec.emplace_back((std::initializer_list<int>){1,2});
}
答案 1 :(得分:9)
模板推导不能猜测你的大括号封闭的初始化列表应该是一个向量。你需要明确:
vec.emplace_back(std::vector<double>{0.,0.});
答案 2 :(得分:0)
允许std::vector<double>
构造函数为其int
构造函数使用std::vector<double>(std::initializer_list<double>)
的大括号列表。
emplace_back()
无法通过大括号表达式构造元素,因为它是使用完美转发的模板。标准禁止编译器推断{0,0}
的类型,因此std::vector<double>::emplace_back<std::initializer_list<double>>(std::initializer_list<double>)
不会为emplace_back({})
进行编译。
其他答案指出,emplace_back
可以为类型std::initializer_list<T>
的参数编译,如果不必直接从{{1}推导类型的话}表达式。作为将参数强制转换为{}
的替代方法,可以先构造参数。正如Meyers的条款30(有效的现代C ++)中指出的那样,允许emplace_back
推导括号表达式的类型,并允许完美转发来推导其类型由{{1 }}。
auto
auto
通过调用std::vector<std::vector<double> > vec;
auto int_list = {0, 0}; // int_list is type std::initializer_list<int>
vec.emplace_back(int_list); // instantiates vec.emplace_back<std::initializer_list<int>>
向emplace_back
添加元素,这将触发vec
构造函数,并且std::vector<double>(std::forward<std::initializer_list<int>>(int_list))
的元素将被转换。