我有一位工作的朋友鼓励我永远不要将键/值对分配到空白地图中,如下所示:
int somefunc(map<int, int> somemap) {
somemap.clear();
somemap[12] = 42;
}
他说,由于somemap map变量已被清除,因此somemap [12]是无效访问。我推断,即使在调试模式下进行编译,也没有C ++编译器能够生成不必要地尝试访问上面赋值的somemap [12]的程序集。总是如此,上面的最后一行将编译为与此行相同的程序集:
somemap.insert(标准::对(12,42));
这是真的吗?是否有任何理由通过插入与早期方法进行分配?我更喜欢早期,因为它更短。
答案 0 :(得分:1)
std::map
会覆盖[]
operator,以便在不存在的密钥上调用.insert
。这里没问题。
答案 1 :(得分:1)
是的,如果元素尚不存在,最后一行将始终插入一个元素。
来自section 23.4.4.3 of the C++ standard:
T& operator[](const key_type& x);
- 效果:如果地图中没有等效于x的键,请将value_type(x,T())插入地图。
醇>
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[]
执行以下操作:
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
而言,差异并不重要。对于其他类型,它也无关紧要,即它们应该有一个有效的默认构造函数。