Recommended way to insert elements into map

可能的复制品:
在 STL 映射中,使用 map: : insert 比[] ? 更好吗

我在想,当我在 map 中插入元素时,推荐的方法是什么

map[key] = value;

或者

map.insert(std::pair<key_type, value_type>(key, value));

我做了以下快速测试:

#include <map>
#include <string>
#include <iostream>


class Food {
public:
Food(const std::string& name) : name(name) { std::cout << "constructor with string parameter" << std::endl; }
Food(const Food& f) : name(f.name) { std::cout << "copy" << std::endl; }
Food& operator=(const Food& f) { name = f.name; std::cout << "=" << std::endl; return *this; }
Food() { std::cout << "default" << std::endl; }
std::string name;
};


int main() {
std::map<std::string, Food> m0;


/*
1) constructor with string parameter
2) copy
3) copy
4) copy
*/
m0.insert(std::pair<std::string, Food>("Key", Food("Ice Cream")));


/*
1) constructor with string parameter
2) default
3) copy
4) copy
5) =
*/
// If we do not provide default constructor.
// C2512: 'Food::Food' : no appropriate default constructor available
m0["Key"] = Food("Ice Cream");
}
  1. 我意识到通过使用成员函数 insert,会涉及到较少值的函数调用。那么,使用 insert是一种推荐的方法吗?
  2. 为什么需要缺省构造函数?

I know that insert doesn't overwrite existence key value pair, but map[key] = value does. However, is this the only factor I take into consideration, when try to choose among the both?

怎么样

  1. 表演
  2. 价值缺省构造函数的可用性
  3. ???
221505 次浏览

map[key] = value提供了更简单的语法,更容易读写。

The reason for which you need to have default constructor is that map[key] is evaluated before assignment. If key wasn't present in map, new one is created (with default constructor) and reference to it is returned from operator[].

引用如下:

因为映射容器不允许重复的键值,所以插入操作检查插入的每个元素是否已经在具有相同键值的容器中存在另一个元素,如果存在,则不插入该元素,并且不以任何方式更改其映射值。

因此,如果键已经存在,则 insert 不会更改值,而 [] operator会更改值。

编辑:

这让我想起了最近的另一个问题——为什么使用 at()而不是 [] operator从向量中检索值。显然,如果索引超出界限,at()会抛出异常,而 [] operator不会。在这些情况下,最好查找函数的文档,因为它们会提供所有的详细信息。但一般来说,没有(或者至少不应该有)两个函数/运算符做完全相同的事情。

我的猜测是,在内部,insert()将首先检查条目,然后自己使用 [] operator

  1. insert不是一种推荐的方式-它是插入地图的方式之一。与 operator[]的不同之处在于,insert可以判断元素是否插入到映射中。另外,如果你的班级没有缺省构造函数,你必须使用 insert
  2. operator[]需要缺省构造函数,因为 map 会检查元素是否存在。如果没有,那么它使用缺省构造函数创建一个,并返回一个引用(或者对它的 const 引用)。

因为映射容器不允许重复的键值,所以插入操作检查插入的每个元素是否已经在具有相同键值的容器中存在另一个元素,如果存在,则不插入该元素,并且不以任何方式更改其映射值。

如果要插入新元素,请使用 insert 覆盖现有元素,并且可以验证没有 上一页现有元素:

if ( !myMap.insert( std::make_pair( key, value ) ).second ) {
//  Element already present...
}

如果要覆盖可能存在的元素,请使用 []:

myMap[ key ] = value;
assert( myMap.find( key )->second == value ); // post-condition

此表单将覆盖任何现有条目。