std :: move with std :: make_pair [英] std::move with std::make_pair

查看:90
本文介绍了std :: move with std :: make_pair的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

两者之间是否有区别?

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::map中分配std::pair吗?

Is the std::move redundant here? Will std::map::emplace and perfect forwarding take care of allocating the std::pair directly in the std::map?

推荐答案

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

std::make_pair(...) and std::move(std::make_pair(...)) are both rvalue expressions (the first one is a prvalue, the second one is an xvalue). Since emplace takes forwarding references, both are deduced as the same type, so std::move in this case is redundant, but in a general case, a redundant std::move can inhibit copy-elision.

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

对地图元素的值执行以下初始化:

which performs the following initialization of the map element's value:

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

请注意,这与以下内容不同:

Note that this is different from:

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

前者首先创建一个prvalue对(制作t1t2的副本),然后将其移出(将复制的t1t2都移到p).没有复制删除.

The former first creates a prvalue pair (makes copies of t1 and t2), which is then moved from (moves both the copied t1 and t2 into p). No copy-elision takes place.

后者使用t1t2来初始化存储在该对中的两个T.

The latter uses t1 and t2 to initialize both Ts stored in the pair.

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

To avoid the unnecessary move resulting from the first syntax, you can instead utilize piecewise construction:

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

将从绑定到原始t1t2的引用成员中初始化对中的元素.

that will initialize the elements of the pair from reference members bound to original t1 and t2.

这篇关于std :: move with std :: make_pair的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆