62

C++11std::map<K,V>类型有一个emplace函数,就像许多其他容器一样。

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

std::string val {"hello"};

m.emplace(1, val);

此代码按宣传的方式工作,std::pair<K,V>直接替换,但它会导致复制keyval发生。

是否也可以将值类型直接放入地图中?我们能比将调用中的参数移动到更好emplace吗?


这是一个更彻底的例子:

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
4

2 回答 2

82

您传递的参数map::emplace被转发到 的构造函数map::value_type,即pair<const Key, Value>. 因此,您可以使用分段构造构造函数std::pair避免中间复制和移动。

std::map<int, Foo> m;

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

现场演示

于 2015-01-15T09:46:41.717 回答
32

在 C++17 中,使用该try_emplace方法可以更轻松地实现这一点。

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

标准库的这一新增内容已在论文 N4279中进行了介绍,并且应该已经在Visual Studio 2015GCC 6.1LLVM 3.7(libc++ 库)中得到支持。

于 2016-10-05T18:57:45.253 回答