我看到很多将项目添加到 amap
或unordered_map
via 的示例operator[]
,如下所示:
int main() {
unordered_map <string, int> m;
m["foo"] = 42;
cout << m["foo"] << endl;
}
有什么理由改用insert
成员函数吗?看起来他们都做同样的事情。
我看到很多将项目添加到 amap
或unordered_map
via 的示例operator[]
,如下所示:
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
不会覆盖现有值,并且它返回 a pair<iterator, bool>
,其中iterator
是键的位置,无论它是否已经存在。bool
指示插入是否发生。
operator[]
有效地做一个lower_bound
关键。如果该操作的结果是iterator
具有相同键的 an,则它返回对该值的引用。如果不是,它会插入一个具有默认构造值的新节点,然后返回对该值的引用。这就是为什么operator[]
是一个非常量成员 - 如果它不存在,它会自动激活键值。 如果值类型的构建成本很高,这可能会对性能产生影响。
另请注意,在 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之后)之类的东西似乎比[]
.
因此,是否有任何理由使用插入成员函数? 我会说重叠功能,地狱不。