簡體   English   中英

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::emplaceperfect forwarding可以直接在std::map中分配std::pair

std::make_pair(...)std::move(std::make_pair(...))都是rvalue表達式(第一個是prvalue,第二個是xvalue)。 由於emplace采用轉發引用,因此兩者都被推導為相同的類型,因此在這種情況下std::move是多余的,但在一般情況下,冗余的std::move可以禁止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));

它執行map元素值的以下初始化:

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

前者首先創建一個prvalue對(制作t1t2副本),然后將其移出(將復制的t1t2移動到p )。 不會發生任何復制。

后者使用t1t2來初始化存儲在該對中的兩個T s。

為了避免第一種語法產生不必要的移動,您可以改為使用分段構造:

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引用成員初始化該對的元素。

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

將調用移動構造函數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM