Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 
like image 901
Drew Noakes Avatar asked Jan 15 '15 09:01

Drew Noakes


People also ask

Does map insert copy?

Yes -- when you insert an item into an std::map, you pass it by value, so what it contains is a copy of what you passed.

What is MAP emplace?

The map::emplace() is a built-in function in C++ STL which inserts the key and its element in the map container. It effectively increases the container size by one.

Is std::map ordered?

Yes, a std::map<K,V> is ordered based on the key, K , using std::less<K> to compare objects, by default.


2 Answers

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

like image 132
Praetorian Avatar answered Oct 14 '22 13:10

Praetorian


In C++17 this can more easily be achieved with the try_emplace method.

map<int,Foo> m; m.try_emplace(1, 2.3, "hello"); 

This addition to the standard library was covered in paper N4279 and should already be supported in Visual Studio 2015, GCC 6.1 and LLVM 3.7 (the libc++ library).

like image 29
James Holderness Avatar answered Oct 14 '22 12:10

James Holderness