C++ 向地图中插入元素的推荐方法
可能重复:C++ 向地图中插入元素的推荐方法,c++,stl,stdmap,C++,Stl,Stdmap,可能重复: 我想知道,当我在地图中插入元素时,推荐的方法是什么。我应该吗 map[key] = value; 或 map.insert(std::pair(key,value)); 我做了以下快速测试: #include <map> #include <string> #include <iostream> class Food { public: Food(const std::string& name) : name(name) {
我想知道,当我在地图中插入元素时,推荐的方法是什么。我应该吗
map[key] = value;
或
map.insert(std::pair(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");
}
#包括
#包括
#包括
等级食品{
公众:
食物(const std::string&name):名称(name){std::coutmap[key]=value
是为了更简单的语法而提供的。它更易于读写
您需要使用默认构造函数的原因是分配前会计算map[key]
。如果map中不存在key,则会创建一个新的构造函数(使用默认构造函数),并从操作符[]
返回对它的引用以引用:
由于映射容器不允许重复的键值,因此插入操作会检查插入的每个元素在容器中是否已存在具有相同键值的其他元素,如果存在,则不会插入该元素,并且不会以任何方式更改其映射值
因此,如果键已经存在,insert将不会更改值,[]运算符将更改该值
编辑:
这让我想起了最近的另一个问题-为什么要使用at()
而不是[]操作符
从向量中检索值。显然at()
在索引超出范围时抛出异常,而[]运算符
不会。在这种情况下,最好查阅函数的文档,因为它们会为您提供所有详细信息。但一般来说,没有(或至少不应该有)两个函数/运算符执行完全相同的操作
我的猜测是,在内部,insert()
将首先检查条目,然后自己使用[]操作符
insert
不是推荐的方法-它是插入到映射中的方法之一。与操作符[]
的区别在于insert
可以判断元素是否插入到映射中。此外,如果您的类没有默认构造函数,则必须使用insert
运算符[]
需要默认构造函数,因为映射会检查元素是否存在。如果不存在,则使用默认构造函数创建一个元素,并返回一个引用(或对该元素的常量引用)
由于映射容器不允许重复的键值,因此插入操作会检查插入的每个元素在容器中是否已经存在具有相同键值的其他元素,如果存在,则不会插入该元素,并且不会以任何方式更改其映射值。如果要插入新的元素,请使用插入nt.插入
将不会
覆盖现有元素,您可以验证是否没有
先前存在的元素:
if ( !myMap.insert( std::make_pair( key, value ) ).second ) {
// Element already present...
}
myMap[ key ] = value;
assert( myMap.find( key )->second == value ); // post-condition
如果要覆盖可能存在的元素,请使用[]
:
if ( !myMap.insert( std::make_pair( key, value ) ).second ) {
// Element already present...
}
myMap[ key ] = value;
assert( myMap.find( key )->second == value ); // post-condition
此表单将覆盖任何现有条目。除非您看到性能受到严重影响,否则为什么要费心键入第一个条目?此外,一个好的优化器可能会删除一些副本为什么不这样看:如果您从未期望重复值,请使用插入
否则使用映射[key]=value
这没有提到最重要的区别,如果元素已经存在,则插入不起任何作用。这很好,但它不能帮助我在不创建无参数构造函数的情况下强制插入。我可以这样做吗…不需要插入、检查、删除、插入?这不仅仅是语法。map[key]=value;
和map.insert({key,value});
在映射已经包含键的值时是不一样的实际上,反之亦然,至少在GNU libstdc++中是这样:操作符[]
查找现有元素,如果找不到,则使用默认构造的值调用insert
。