繁体   English   中英

使用初始化列表放置向量

[英]Emplacement of a vector with initializer list

我有一个std::vector<std::vector<double>>并想在它的末尾添加一些元素,所以这是我的试验:

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

但这不会编译,而以下将执行:

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

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

谢谢你的帮助。

前面的答案提到,当您在线构造向量并放置它时,您可以获得要编译的代码。 但是,这意味着您正在临时向量上调用移动构造函数,这意味着您没有就地构造向量,而这就是使用emplace_back而不是push_back的全部原因。

相反,您应该将初始化列表转换为一个initializer_list ,如下所示:

#include <vector>
#include <initializer_list>

int main()
{
    std::vector<std::vector<int>> vec;
    vec.emplace_back((std::initializer_list<int>){1,2});
}

模板推导无法猜测您的大括号括起来的初始化列表应该是一个向量。 你需要明确:

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

请注意,这会构造一个向量,然后使用std::vector的移动复制构造函数将其移动到新元素中。 所以在这种特殊情况下,它没有超过push_back()优势。 @TimKuipers 的回答显示了解决此问题的方法。

这里真的有两个问题:数字类型转换和模板参数推导。

允许std::vector<double>构造函数对其std::vector<double>(std::initializer_list<double>)构造函数使用花括号列表(甚至是int std::vector<double>(std::initializer_list<double>) (但是请注意, std::initializer_list<int>不会隐式转换为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<vector::value_type>类型的参数编译,但不会直接从{}表达式推导出此类型。

作为将参数转换为emplace_back的替代方法,您可以先构造参数。 正如 Meyers 的 Item 30 (Effective Modern C++) 所指出的,允许auto将大括号表达式的类型推导出为std::initializer_list<T> ,并且允许完美转发推导出其类型被推导的对象的类型通过auto

std::vector<std::vector<double> > vec;
auto double_list = {0., 0.}; // int_list is type std::initializer_list<int>
vec.emplace_back(double_list); // instantiates vec.emplace_back<std::initializer_list<double>&>

emplace_back通过调用std::vector<double>(std::forward<std::initializer_list<double>>(double_list))vec添加一个元素,这会触发std::vector<double>(std::initializer_list<double>)构造函数。

参考:第 17.8.2.5 节第 5.6 项表明这是一个非推导上下文,用于 17.8.2.1 第 1 项下的模板参数推导。

更新:此答案的早期版本错误地暗示可以提供std::initializer_list<int>代替std::initializer_list<double>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM