【问题标题】:Operator[] in std::map implementationstd::map 实现中的运算符 []
【发布时间】:2016-10-12 23:24:32
【问题描述】:

我正在尝试在 C++ 中实现像 std::map 这样的容器。我在重载运算符 [] 时有一个小查询。我看到这个运算符有两种工作方式:

  1. mymap[2] - 在这种情况下,它会在 map 中查找键 2 并针对该键返回值。
  2. mymap[2]=3 - 在这种情况下,它会在 map 中查找键 2,如果未找到键,则在 map 中插入 3。

我看到这个运算符的声明看起来像:Mapped_T &operator[](const Key_T &); 但我没有得到的是,如果找不到密钥,我将不得不在 Map 中插入一个新元素,但在 operator[] 函数的声明中我看不到任何地方传递的价值。那么重载的运算符如何知道要插入的键的值是什么?

【问题讨论】:

标签: c++ stl


【解决方案1】:

当键不存在时,std::map 使用值类的默认构造函数构造一个新值,并返回对新插入值的引用。

【讨论】:

  • 但在这种情况下,如何将实际值插入到该键上?
  • 正如我向您解释的那样:实际值是使用对象的默认构造函数构造并插入的。对于简单类型,默认构造函数是零初始化。
  • 抱歉,我还是没听明白。如果我调用 mymap[2]=3 (假设 key 现在不存在,那么 1. [] 的重载运算符被称为 2. Key 2 插入了一些默认值,假设它现在为 NULL。但是在这整个process 5是怎么插入的?
  • 默认值为0。而5是从哪里来的呢?这里没有5。插入键 2,值为 0,operator[] 然后返回对该值的引用,= 运算符为其分配 3。
  • 不知道为什么你会被否决。这是一个有效的答案。
【解决方案2】:

它会被值初始化——就像{}一样,这里有一些伪代码:

Mapped_T & operator[](const Key_T &k) {
    if(!has_key(k))
        insert(k, Mapped_T{});
    return at(k);
}

您问题的重要部分是Mapped_T{}。对于聚合,这意味着零初始化,对于具有默认构造函数的类,这意味着使用该构造函数。

【讨论】:

  • 所以你的意思是调用 intializer_list 来根据 map 中的键复制实际值?
  • 不,这段代码中没有initializer_list
猜你喜欢
  • 2017-05-31
  • 1970-01-01
  • 2016-11-21
  • 1970-01-01
  • 2011-07-10
  • 2014-07-15
  • 1970-01-01
  • 2012-01-12
  • 1970-01-01
相关资源
最近更新 更多