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
的參考成員。
這裏涉及到兩個'std :: pair's。 –