【问题标题】:Why does std::map not have an insert function of type insert(key &k, val &v)为什么 std::map 没有 insert(key &, value & v) 类型的插入函数
【发布时间】:2016-05-23 21:02:12
【问题描述】:

为什么std::map 不支持如下插入:

std::map<obj1, obj2> map_int;

void insert_map(obj1 &key, obj2 &val)
{
    map_int.insert(key, val);
}

我知道上面是不正确的。我想知道是什么阻止了这样设计插入功能。它比创建一对 IMO 更直观。

【问题讨论】:

  • 这不是map[key] = val 所做的吗?
  • FWIW,使用 C++11,你应该可以使用map.intsert({key, val});
  • @Barmar,如果存在具有给定键的项目,它将替换该值。如果有给定键的项目,insert 将不会替换该值。
  • @Barmar 这还涉及到默认构造一个值——这可能是不可取的或不可能的。

标签: c++ c++11 std c++-standard-library


【解决方案1】:

它叫emplace()

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

// uses pair's template constructor
m.emplace("d", "ddd");

【讨论】:

  • 再次为什么需要pair?为什么不能简单地插入(key, val)?
  • @mc_87 emplace(key, value) 正在执行您的要求,唯一的区别是函数的名称。
  • @0xhacker,可能是为了与所有其他采用value_type 插入的 STL 容器保持一致。通用代码受益于这种一致性。但是,如果用例足够好,额外的重载可能会带来好处。
  • 不,我更想知道为什么需要在 stl 映射中插入对构造函数?我认为没有暴露更简单的界面有更深层次的原因。插入键和值肯定有一些问题,使用一对必须解决。我想知道问题所在。知道它无缘无故地复杂起来会很难过。
  • @0xhacker 因为在后台,std::mapvalue_typestd::pair&lt;first_type, second_type&gt;
【解决方案2】:

在 C++17 中,您可以使用:

map_int.try_emplace(key, val);

这实际上返回了一些有用的信息:

std::pair<std::map<obj1, obj2>::iterator, bool> p = map_int.try_emplace(key, val);
  • p.first 是一个迭代器,它指向具有给定键的元素。
  • p.second 表示插入是否发生。

您可以在 C++11 中使用map_int.emplace(key, val) 实现类似的效果,但存在一些细微差别(与值的复制/移动有关)。此外,try_emplace 允许方便地构造任意元素:

struct X { X(int, char, bool); };

std::map<int, X> m;
m.try_emplace(10, 20, 'x', false);  // constructs X(20, 'x', false) if new

C++11 中的类似操作如下所示:

m.emplace(
    std::piecewise_construct,
    std::forward_as_tuple(10),
    std::forward_as_tuple(20, 'x', false));

【讨论】:

  • 顺便说一句,C++17 也有std::map::insert_or_assign,如果你真正想要做的是如果键存在则覆盖旧值,或者如果不存在则插入对。
【解决方案3】:

std::map 确实 有一个insert() 方法(实际上是几个),它只是具有与您期望的不同的签名。您需要向它传递一个包含所需键和值的std::pair,例如:

std::map<obj1, obj2> map_int;

void insert_map(obj1 &key, obj2 &val)
{
    map_int.insert(std::make_pair(key, val));
}

【讨论】:

  • 我知道这行得通。在这个问题中,我明确地说只插入 key 和 val 比创建一对更直观。我的问题是为什么 stl map 的设计者/实现者没有更简单的界面。为什么需要用pair来复杂化呢?
  • 我相信其他 cmets 已经涵盖了这一点。 std::mapstd::pair 值的容器,与其他容器一样,您必须使用其 value_type 将新值插入其中,在本例中为 std::pair。如果您想知道为什么该标准没有定义更简单的接口,请询问设计该接口的 C++ 委员会。
猜你喜欢
  • 2012-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-03
  • 1970-01-01
  • 1970-01-01
  • 2019-08-08
相关资源
最近更新 更多