2016-04-28 3 views
4

Есть ли разница между:станд :: двигаться станд :: 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::pair непосредственно в std::map?

+0

Здесь задействованы две 'std :: pair'. –

ответ

9

std::make_pair(...) и std::move(std::make_pair(...)) - оба выражения rvalue (первый - это 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 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.

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

вызовет конструктор перемещения.

+0

Лучше использовать кусочную конструкцию в этом случае, что не приведет к копиям * или *. –

Смежные вопросы