的std ::性病:: make_pair
问题描述:
移动有什么区别:的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
?
答
std::make_pair(...)
和std::move(std::make_pair(...))
都是右值表达式(第一个是一个prvalue,第二个是一个xvalue)。由于emplace
需要转发参考,因此两者都被推断为相同类型,因此在这种情况下std::move
是多余的,但在一般情况下,冗余std::move
可以禁止复制省略。
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));
执行地图元素的值的以下初始化:
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);
形式r首先创建一个prvalue对(复制t1
和t2
),然后将其从(将复制的t1
和t2
移动到p
)移动。没有复制省略发生。
后者使用t1
和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
和t2
的参考成员。
答
m.emplace(std::make_pair(1, std::make_pair(t1,t2)));
将调用移动构造函数。
+0
在这种情况下更好地使用分段结构,这将导致无法移动*或*副本。 –
这里涉及到两个'std :: pair's。 –