[英]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
?
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對(制作t1
和t2
副本),然后將其移出(將復制的t1
和t2
移動到p
)。 不會發生任何復制。
后者使用t1
和t2
來初始化存儲在該對中的兩個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)));
這將從綁定到原始t1
和t2
引用成員初始化該對的元素。
m.emplace(std::make_pair(1, std::make_pair(t1,t2)));
將調用移動構造函數。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.