繁体   English   中英

在map或unordered_map中是必需的insert()吗?

[英]is insert() necessary in a map or unordered_map?

我看到很多通过operator[]将项添加到mapunordered_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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM