std :: move with std :: make_pair

时间:2016-04-28 06:10:19

标签: c++ c++11 dictionary move

之间有什么区别:

std::map <int,std::pair<T,T>> m;
T t1,t2;
m.emplace(1,std::make_pair(t1,t2));

std::map <int,std::pair<T,T>> m;
T t1,t2;
m.emplace(1,std::move(std::make_pair(t1,t2)));

此处std::move多余? std::map::emplaceperfect forwarding会直接在std::pair中分配std::map吗?

2 个答案:

答案 0 :(得分:13)

std::make_pair(...)std::move(std::make_pair(...))都是右值表达式(第一个是prvalue,第二个是xvalue)。由于emplace采用转发引用,因此两者都被推断为相同的类型,因此在这种情况下std::move是多余的,但在一般情况下,冗余std::move可以禁止复制省略。 / p>

m.emplace(1, std::make_pair(t1, t2));

相当于:

auto&& arg = std::make_pair(t1, t2);
std::pair<const int, std::pair<T, T>> e(1, std::forward<std::pair<T, T>>(arg));

执行map元素值的以下初始化:

auto&& arg = std::make_pair(t1, t2);
std::pair<T, T> p(std::forward<std::pair<T, T>>(arg));

请注意,这与:

不同
std::pair<T, T> p(t1, t2);

前者首先创建一个prvalue对(制作t1t2的副本),然后将其移出(将复制的t1t2移动到{ {1}})。不会发生任何复制。

后者使用pt1来初始化对中存储的t2个。

为避免第一种语法产生不必要的移动,您可以改为使用分段构造:

T

这相当于:

m.emplace(std::piecewise_construct
        , std::forward_as_tuple(1)
        , std::forward_as_tuple(t1, t2));

将从绑定到原始auto&& arg = std::tuple<T&, T&>(t1, t2); std::pair<T, T> p(std::get<0>(std::forward<std::tuple<T&, T&>>(arg)) , std::get<1>(std::forward<std::tuple<T&, T&>>(arg))); t1的参考成员初始化该对的元素。

答案 1 :(得分:0)

<div class="arrow-right">
  <p> next </p>
</div>

将调用move构造函数。