我很想知道,当我将元素插入地图时,推荐的方式是什么。我应该
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");
}
insert
来实现,将涉及较少值的函数调用。那么,推荐使用insert
吗?map[key] = value
方式时,为什么需要默认构造函数?我知道insert
不会覆盖存在键值对,但map[key] = value
会覆盖。但是,当我尝试在两者中进行选择时,这是我考虑的唯一因素吗?
怎么样
答案 0 :(得分:61)
insert
不是推荐的方式 - 它是插入地图的方式之一。与operator[]
的区别在于insert
可以判断元素是否已插入到地图中。此外,如果您的类没有默认构造函数,则您被迫使用insert
。 operator[]
需要默认构造函数,因为map会检查元素是否存在。如果没有,那么它使用默认构造函数创建一个并返回一个引用(或对它的const引用)。因为映射容器不允许重复键值,所以插入操作检查插入的每个元素是否已经在具有相同键值的容器中存在另一个元素,如果是,则不插入元素并且其映射值不是以任何方式改变。
答案 1 :(得分:41)
如果要插入新元素,请使用insert
。 insert
不会
覆盖现有元素,您可以验证没有
以前的元素:
if ( !myMap.insert( std::make_pair( key, value ) ).second ) {
// Element already present...
}
如果要覆盖可能存在的元素,请使用[]
:
myMap[ key ] = value;
assert( myMap.find( key )->second == value ); // post-condition
此表单将覆盖任何现有条目。
答案 2 :(得分:13)
引用:
因为映射容器不允许重复键值,所以插入操作检查插入的每个元素是否已经在具有相同键值的容器中存在另一个元素,如果是,则不插入元素并且其映射值不是以任何方式改变。
因此,如果密钥已存在,则insert不会更改值,[] operator
将会。
编辑:
这让我想起了最近的另一个问题 - 为什么使用at()
代替[] operator
来检索向量中的值。如果索引超出范围,显然at()
会抛出异常,而[] operator
则不会。在这些情况下,最好查看功能文档,因为它们会为您提供所有详细信息。但总的来说,没有(或者至少不应该)两个函数/运算符完全相同。
我的猜测是,在内部,insert()
将首先检查条目,然后自己使用[] operator
。
答案 3 :(得分:9)
map[key] = value
用于提供更简单的语法。它更容易阅读和写作。
您需要拥有默认构造函数的原因是在分配之前评估map[key]
。如果map中没有key,则创建一个new(使用默认构造函数),并从operator[]
返回对它的引用。