[英]is insert() necessary in a map or unordered_map?
我看到很多通过operator[]
将项添加到map
或unordered_map
的示例,如下所示:
int main() {
unordered_map <string, int> m;
m["foo"] = 42;
cout << m["foo"] << endl;
}
是否有任何理由使用insert
成员函数? 看起来他们都做同样的事情。
他们不是。
operator[]
将覆盖此键的值(如果存在),而insert
不会。
如果operator[]
用于插入元素,则预计会稍慢一些(详见@ MatthieuM的评论),但这并不重要。
而std::map::insert
返回std::pair< iterator, bool >
,其中.second
将告诉您该值是否已插入或已存在。
关于你的评论:你不能拥有2个具有相同键和不同值的元素。 这不是multimap
。
如果地图中有一个元素,并且您尝试插入相同的键,则:
operator[]
将覆盖现有值 std::map::insert
std::pair< iterator, bool >
,其中.second
将为false
(表示“未插入新元素,因为此键已经存在”)并且.first
将指向找到的元素。 *由于来自@ luk32的注释/备注,我改变了这一点; 但通过写“不会做任何事”,我并不是字面意思,我的意思是它不会改变现有元素的价值
使用insert()
可以帮助提高某些情况下的性能(更具体地说,对于std::map
因为搜索时间是O(log(n))
而不是常量摊销)。 采用以下常见示例:
std::map<int, int> stuff;
// stuff is populated, possibly large:
auto iterator = stuff.find(27);
if(stuff.end() != iterator)
{
// subsequent "find", set to 15
iterator->second = 15;
}
else
{
// insert with value of 10
stuff[27] = 10;
}
上面的代码有效地找到了两次元素。 我们可以这样(略微)更有效地编写如下:
// try to insert 27 -> 10
auto result = stuff.insert(std::make_pair(27, 10));
// already existed
if(false == result.second)
{
// update to 15, already exists
result.first->second = 15;
}
上面的代码只试图找到一次元素,降低了算法的复杂性。 对于频繁操作,这可以大大提高性能。
这两者并不相同。 insert
不会覆盖现有值,并返回一pair<iterator, bool>
,其中iterator
是键的位置,无论它是否已经存在。 bool
表示插入是否发生。
operator[]
有效地在key上执行lower_bound
。 如果该操作的结果是具有相同键的iterator
,则返回对该值的引用。 如果不是,则插入具有默认构造值的新节点,然后返回对该值的引用。 这就是operator[]
是非const成员的原因 - 如果键值不存在,它会自动生成键值。 如果值类型构造成本高,则可能会对性能产生影响。
另请注意,在C ++ 11中,我们有一个emplace
方法,它与insert
几乎相同,只不过它会在转发参数的情况下就位构造键值对,如果发生插入的话。
好吧,我不同意Kiril在某种程度上的答案,我认为它不完整,所以我给了我。
根据cppreference
std::map::operator[]
相当于某个insert()
调用。 通过这个我也认为他错了,说价值会被覆盖。 它说:“返回值如果没有带键键的元素,则引用新元素的映射值。否则返回对现有元素的映射值的引用。”
所以它似乎是一个方便的包装器。 但是insert()
具有重载的优点,因此它在一个名称下提供了更多功能。
我向Kiril说明,乍一看他们似乎确实有一些不同的功能,但是IHMO他提供的例子并不相同。
因此,作为使用insert
的示例/原因,我会指出,一次插入多个元素,或使用hint
( 此处调用3-6)。
那么map或unordered_map中是否需要insert()? 我会说是的。 此外, operator[]
不是必需的,因为它可以使用insert
模拟/实现,而另一种方式是不可能的! 它只是提供了更多的功能。 但是,编写类似(insert(std::make_pair(key, T())).first)->second)
(在cppreference之后)似乎比[]
麻烦。
因此,有没有理由使用插入成员函数? 我会说功能重叠,不行。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.