std :: move with std :: make_pair [英] 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::emplace
和perfect 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对(制作t1
和t2
的副本),然后将其移出(将复制的t1
和t2
都移到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.
后者使用t1
和t2
来初始化存储在该对中的两个T
.
The latter uses t1
and t2
to initialize both T
s 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)));
将从绑定到原始t1
和t2
的引用成员中初始化对中的元素.
that will initialize the elements of the pair from reference members bound to original t1
and t2
.
这篇关于std :: move with std :: make_pair的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!