C ++空映射赋值:equals vs insert

时间:2013-12-13 19:01:50

标签: c++ map

我有一位工作的朋友鼓励我永远不要将键/值对分配到空白地图中,如下所示:

int somefunc(map<int, int> somemap) {
    somemap.clear();
    somemap[12] = 42;
}

他说,由于somemap map变量已被清除,因此somemap [12]是无效访问。我推断,即使在调试模式下进行编译,也没有C ++编译器能够生成不必要地尝试访问上面赋值的somemap [12]的程序集。总是如此,上面的最后一行将编译为与此行相同的程序集:

somemap.insert(标准::对(12,42));

这是真的吗?是否有任何理由通过插入与早期方法进行分配?我更喜欢早期,因为它更短。

6 个答案:

答案 0 :(得分:1)

std::map会覆盖[] operator,以便在不存在的密钥上调用.insert。这里没问题。

答案 1 :(得分:1)

是的,如果元素尚不存在,最后一行将始终插入一个元素。

来自section 23.4.4.3 of the C++ standard

T& operator[](const key_type& x);
  
      
  1. 效果:如果地图中没有等效于x的键,请将value_type(x,T())插入地图。
  2.   

map::[] operator定义为:

  

返回对映射到等效于key的键的值的引用,如果此类键尚不存在则执行插入。

答案 2 :(得分:0)

[]它重载了运算符,所以代码为

    operator[](const key_type& __k)
    {
       // concept requirements
     __glibcxx_function_requires(_DefaultConstructibleConcept<mapped_type>)

      iterator __i = lower_bound(__k);
     // __i->first is greater than or equivalent to __k.
      if (__i == end() || key_comp()(__k, (*__i).first))
           __i = insert(__i, value_type(__k, mapped_type()));
      return (*__i).second;
   }
从这里你可以看到,如果它是空的,它将被插入

答案 3 :(得分:0)

地图的operator[]执行以下操作:

  • 找到元素(键)。如果找到则返回对它的引用(值&amp;)。
  • 如果未找到,请创建一个空元素pair<key,value(default value)>并返回对该值的引用。

operator []的问题不同。有些人想用它来搜索元素是否存在。这是错误的,因为地图将填满空元素。对于搜索,人们应该使用map.find()

答案 4 :(得分:0)

这两种用法的含义略有不同:

somemap[12] = 42;

如果某个地图[12]存在,则会替换现有值,如果不存在则会插入新值。

auto returnValue = somemap.insert<std::make_pair(12, 42));

将为somemap [12]插入一个新值(如果尚不存在),或者如果已经存在12的映射则保持值不变。您可以判断它是否如此工作:

if(returnValue.second)
{
   // it worked.  
   // returnValue.first is an iterator pointing to the newly added element
}
else
{
    // it failed.
    // returnvalue.first is an iterator pointing to the unchanged pre-existing element.
}

答案 5 :(得分:0)

最好的方法是衡量。但是,库将定位键的位置,如果不存在,则添加具有键和默认构造值的新节点。然后它返回一个作出分配的引用:库没有看到指定的值,即它可以做道德等同于

map.insert(std::make_pair(12, 42));

如果编译器能够检测到它可以执行此操作,我会感到惊讶。对于int而言,差异并不重要。对于其他类型,它也无关紧要,即它们应该有一个有效的默认构造函数。