具有初始化列表的向量的放置

时间:2014-07-03 10:14:56

标签: c++ emplace

我有一个std::vector<std::vector<double>>,并想在最后添加一些元素,所以这是我的试用版:

std::vector<std::vector<double> > vec;
vec.emplace_back({0,0});

但是这不会编译,而以下将会这样做:

std::vector<double> vector({0,0});

为什么emplace_back不能在这个位置构建元素?或者我做错了什么?

感谢您的帮助。

3 个答案:

答案 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))的元素将被转换。