2016-04-28 52 views
4

移动有什么区别:的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

+0

这里涉及到两个'std :: pair's。 –

回答

9

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对(复制t1t2),然后将其从(将复制的t1t2移动到p)移动。没有复制省略发生。

后者使用t1t2来初始化存储在该对中的两个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))); 

,将初始化所述对的元素来自原始t1t2的参考成员。

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

将调用移动构造函数。

+0

在这种情况下更好地使用分段结构,这将导致无法移动*或*副本。 –

相关问题