std::make_pair(...)
und std::move(std::make_pair(...))
sind beide rvalue Ausdrücke (der erste ist ein prvalue, der zweite ist ein xvalue). Da emplace
Forwarding-Referenzen übernimmt, werden beide als gleicher Typ abgeleitet, so dass std::move
in diesem Fall redundant ist, aber in einem generellen Fall kann ein redundanter std::move
Kopier-Elision verhindern.
m.emplace(1, std::make_pair(t1, t2));
entspricht:
auto&& arg = std::make_pair(t1, t2);
std::pair<const int, std::pair<T, T>> e(1, std::forward<std::pair<T, T>>(arg));
die die folgende Initialisierung des Wertes des Kartenelement durchführt:
auto&& arg = std::make_pair(t1, t2);
std::pair<T, T> p(std::forward<std::pair<T, T>>(arg));
anzumerken, dass diese aus unterschiedlichen ist:
std::pair<T, T> p(t1, t2);
Die Form r erzeugt zuerst ein Prvalue-Paar (erstellt Kopien von t1
und t2
), von dem dann die (t1
und t2
in p
kopierten) verschoben werden. Es findet keine Kopier-Elision statt.
Letzterer verwendet t1
und t2
, um beide im Paar gespeicherten T
s zu initialisieren.
Um eine unnötige Bewegung zu vermeiden, die aus der ersten Syntax führt, Sie stattdessen stückweise Konstruktion nutzen können:
m.emplace(std::piecewise_construct
, std::forward_as_tuple(1)
, std::forward_as_tuple(t1, t2));
, die gleichwertig sein wird:
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)));
, die die Elemente des Paares initialisieren wird von Referenzmitgliedern, die an Original t1
und t2
gebunden sind.
Hier sind zwei 'std :: -Paare beteiligt. –