W tym przypadku nie ma sensu emplacing części z „wartości typu” std::pair
, jak std::string
może zarówno być skutecznie przekształcony z C-string, a może być skutecznie przeniesiony na mapę. Proste m.emplace(3, std::make_pair("bob", "alice"))
i jesteś 99% drogi do optymalnej wydajności.
Jednakże, jeśli masz std::map
który mapuje się do rodzaju, które nie mogą być skutecznie skonstruowane w taki sposób, C++ 11 zapewnia std::piecewise_construct
dla std::pair
być emplace
d.
struct A { }; // nothing
struct C { C(C&&)=delete; }; // no copy/move
struct B { B()=delete; B(B&&)=delete; B(C&&, C&&) {}; }; // no copy/move, only annoying ctor
std::map< int, std::pair<A,B> > test;
// test.emplace(0, std::make_pair(A{}, B{}); // does not compile
// test.emplace(0, std::make_pair(A{}, B{C{},C{}}); // does not compile
test.emplace(std::piecewise_construct,
std::make_tuple(0),
std::forward_as_tuple(
std::piecewise_construct,
std::forward_as_tuple(A{}),
std::forward_as_tuple(C{}, C{})
)
); // compiles!
live example
Jest to skrajny przypadek rogu, jako obiekty wydajny-Move są znacznie bardziej powszechne.
rozszerzając to - 'emplace' nie tworzy obiektu, a następnie przenosi go do pojemnika; używa * przekazywania * do przekazywania argumentów do kontenera, a następnie kontener wywołuje konstruktor obiektu, gdy kontener wykryje, gdzie w pamięci chce zbudować obiekt. (Myląca nazwa funkcji!) –