2016-04-28 51 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

在這種情況下更好地使用分段結構,這將導致無法移動*或*副本。 –

相關問題