问题 使用std :: make_unique的push_back或emplace_back


根据答案 这些  问题  这里,我知道使用c ++ 14肯定是首选 std::make_unique 而不是 emplace_back(new X) 直。

那就是说,打电话是首选

my_vector.push_back(std::make_unique<Foo>("constructor", "args"));

要么

my_vector.emplace_back(std::make_unique<Foo>("constructor", "args"));

也就是说,我应该使用 push_back 要么 emplace_back 添加时 std::unique_ptr 由...构建 std::make_unique

====编辑====

为什么? c:< - (微笑)


12539
2018-03-17 00:16


起源

使用向量的项类型的实际参数, push_back 和 emplace_back 必须这样做。 - Cheers and hth. - Alf
有关: htmlpreview.github.io/?https://github.com/HowardHinnant/papers/... - dyp
@Praetorian呐喊谢谢。 - NHDaly
如果您有自定义删除器 unique_ptr然后事情就会改变。 - Yakk - Adam Nevraumont


答案:


就新物体的构造而言,它没有任何区别;你已经有了 unique_ptr<Foo> prvalue(调用的结果) make_unique)所以两者 push_back 和 emplace_back 会打电话给 unique_ptr 构造要附加到的元素时移动构造函数 vector

如果您的用例涉及在插入后访问新构造的元素,那么 emplace_back 从C ++ 17开始更方便,因为它返回对元素的引用。而不是

my_vector.push_back(std::make_unique<Foo>("constructor", "args"));
my_vector.back().do_stuff();

你可以写

my_vector.emplace_back(std::make_unique<Foo>("constructor", "args")).do_stuff();

10
2018-03-17 00:22



是同意,这就是我问的原因。 :) - NHDaly
@NHDaly考虑接受这个答案? - laike9m
@ laike9m完成,谢谢! - NHDaly
实际上,存在差异...... emplace_back() 返回对添加元素的引用,而 push_back() 返回无效。 emplace_back(std::make_unique<>()) 因此,在添加对象后需要使用对象的上下文中非常有用。 - Jamie Bullock
@JamieBullock嗯,3年前我回答这个问题没有什么区别。更新了答案,将C ++ 17更改包含在返回类型中。谢谢。 - Praetorian


明确地

template<class T, class A, class...Args>
void push_unique( std::vector<std::unique_ptr<T>,A>& v, Args&&...args ) {
  v.push_back( std::make_unique<T>(std::forward<Args>(args)...) );
}

是最好的选择:

push_unique(my_vector,"constructor", "args");

遗憾的是,这是前缀表示法:(运算符,容器,参数...)vs infix(容器运算符参数...)。

如果只有一种方法可以使其成为中缀,就像 扩展方法 要么 命名运营商

因为那会很酷。


0
2018-03-17 21:16