Skip to content

emplace

C++ map emplace class mapped_type

对于mapped_typeclass的,如何实现emplace呢?

stackoverflow std::map emplace without copying value

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

NOTE: 在C++11中,还不支持这种写法,C++17支持了

A

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

A

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).

Comments

Yes, try_emplace() is really the best solution. In particular, emplace() always constructs a Key-Value pair on the heap. So, if the Key is actually found in the table, emplace() will delete that just newly constructed Key-Value pair again. try_emplace on the contrary does everything in the expected order: Check, if they Key exists, and if yes, return an iterator to that Key-Value pair. If not, then it emplaces the new Key and Value into the container. – Kai Petzke Sep 12 '19 at 0:06

cppreference std::unordered_map::emplace

cppreference try_emplace