Drew Noakes Drew Noakes - 1 month ago 22
C++ Question

std::map emplace without copying value

The C++11

std::map<K,V>
type has an
emplace
function, as do many other containers.

std::map<int,std::string> m;

std::string val {"hello"};

m.emplace(1, val);


This code works as advertised, emplacing the
std::pair<K,V>
directly, however it results in a copy of
key
and
val
taking place.

Is it possible to emplace the value type directly into the map as well? Can we do better than moving the arguments in the call to
emplace
?




Here's a more thorough example:

struct Foo
{
Foo(double d, string s) {}
Foo(const Foo&) = delete;
Foo(Foo&&) = delete;
}

map<int,Foo> m;
m.emplace(1, 2.3, string("hello")); // invalid

Answer

The arguments you pass to map::emplace get forwarded to the constructor of map::value_type, which is pair<const Key, Value>. So you can use the piecewise construction constructor of std::pair to avoid intermediate copies and moves.

std::map<int, Foo> m;

m.emplace(std::piecewise_construct,
          std::forward_as_tuple(1),
          std::forward_as_tuple(2.3, "hello"));

Live demo

Comments