std::make_pair(...)
and std::move(std::make_pair(...))
都是右值表达式(第一个是右值,第二个是x值)。自从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);
前者首先创建一个纯右值对(复制t1
and t2
),然后从 (移动复制的t1
and t2
into p
)。不会发生复制省略。
后者使用t1
and 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
and t2
.