【问题标题】:How to create new entry in std::map without copying the entry value - no pointers如何在 std::map 中创建新条目而不复制条目值 - 没有指针
【发布时间】:2015-12-01 13:50:35
【问题描述】:

我有一张地图:

std::map<std::string, MyDataContainer>

MyDataContainer 是一些classstruct(没关系)。现在我想创建一个新的数据容器。假设我想使用可用的默认构造函数:

// This is valid, MyDataContainer doesn't need constructor arguments
MyDataConstructor example;
// The map definition
std::map<std::string, MyDataContainer> map;
std::string name("entry");
// This copies value of `example`
map[name] = example;
// Below, I want to create entry without copy:
std::string name2 = "nocopy"
// This is pseudo-syntax
map.createEmptyEntry(name2);

有没有办法做到这一点?当我只想在地图中初始化它时跳过创建辅助变量?是否可以使用构造函数参数来做到这一点?

我认为这个问题也适用于其他标准容器,例如

【问题讨论】:

标签: stdvector stdlist c++ c++11 std stdmap


【解决方案1】:

使用emplace:

#include <map>
#include <string>
#include <tuple>

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

m.emplace(std::piecewise_construct,
          std::forward_as_tuple("nocopy"),
          std::forward_as_tuple());

这可以概括为新键值和映射值的任意构造函数参数,您只需将它们粘贴到相应的 forward_as_tuple 调用中。

在 C++17 中,这要容易一些:

m.try_emplace("nocopy"  /* mapped-value args here */);

【讨论】:

  • 有没有相关的危险?我不记得曾经见过它在使用中,这就是我好奇的原因。在文档中,它开始于“Careful use of emplace allows...”。为什么要小心?
  • @TomášZato:危险在于您忘记了如何拼写,并且您的每个读者都会说 WAT?
  • 什么读者?编译器不会在拼写错误时简单地抛出错误吗?
  • @TomášZato:我假设代码主要是为人类编写的。不言而喻,你的代码可以编译,但真正的困难是,当你离开后,将来是否会有人使用这段代码……
  • @TomášZato:“插入”和“放置”语义之间的区别在于,放置使用显式构造函数,因此您必须小心转换。例如。 m.insert(std::chrono::seconds(1)) 有效,m.insert(10) 无效,但 m.emplace(10) 有效。因此,当您放置时,您通常需要了解类型,而不是插入时。
【解决方案2】:

你可以使用map::emplace:见documentation

m.emplace(std::piecewise_construct,
          std::forward_as_tuple(42), // argument of key constructor
          std::forward_as_tuple());  // argument of value constructor

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-12-07
    • 1970-01-01
    • 2012-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-07
    • 1970-01-01
    相关资源
    最近更新 更多