【问题标题】:push_back or emplace_back with std::make_unique带有 std::make_unique 的 push_back 或 emplace_back
【发布时间】:2015-05-19 07:11:06
【问题描述】:

根据thesequestionshere中的答案,我知道使用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"));

也就是说,当添加由std::make_unique 构造的std::unique_ptr 时,我应该使用push_back 还是emplace_back

==== 编辑 ====

为什么? c:

【问题讨论】:

标签: c++ c++11 stdvector c++14 unique-ptr


【解决方案1】:

就新对象的构造而言,它没有任何区别;你已经有一个unique_ptr&lt;Foo&gt; prvalue(调用make_unique 的结果),所以push_backemplace_back 在构造要附加到vector 的元素时都会调用unique_ptr 移动构造函数。

如果您的用例涉及在插入后访问新构造的元素,那么 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();

【讨论】:

  • 是的,同意,这就是我问的原因。 :)
  • 其实还是有区别的……emplace_back()返回的是添加元素的引用,而push_back()返回的是void。因此,emplace_back(std::make_unique&lt;&gt;()) 在添加对象后需要使用的上下文中很有用。
  • @JamieBullock 好吧,3 年前我回答这个问题时并没有什么不同。更新了答案以包括对返回类型的 C++17 更改。谢谢。
【解决方案2】:

很明显

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");

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

如果有办法让它成为中缀就好了,比如extension methodsnamed operators

因为那会很酷。

【讨论】:

    猜你喜欢
    • 2015-01-15
    • 2017-09-21
    • 2016-11-14
    • 1970-01-01
    • 1970-01-01
    • 2011-05-17
    • 2019-05-22
    • 2021-06-02
    相关资源
    最近更新 更多