向地图中插入元素的推荐方式

Recommended way to insert elements into map

本文关键字:方式 元素 地图 插入      更新时间:2023-10-16

可能重复:
在STL映射中,使用map::insert是否比[]更好?

当我在地图中插入元素时,我想知道推荐的方法是什么。我应该吗

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. 当使用map[key] = value方式时,为什么需要默认构造函数

我知道insert不会覆盖存在键值对,但map[key] = value会覆盖。然而,当我试图在两者中进行选择时,这是我唯一考虑的因素吗?

怎么样

  1. 性能
  2. 值的默认构造函数的可用性
  1. insert不是推荐的方式,它是插入到地图中的方式之一。与operator[]的区别在于,insert可以判断元素是否插入到映射中。此外,如果您的类没有默认构造函数,则必须使用insert
  2. operator[]需要默认构造函数,因为映射会检查元素是否存在。如果没有,则使用默认构造函数创建一个,并返回一个引用(或对它的const引用(

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

如果要插入新元素,请使用insertinsert不会覆盖现有元素,您可以验证是否没有以前存在的元素:

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

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

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

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

引用:

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

因此,如果密钥已经存在,insert不会更改值,[] operator会更改。

编辑:

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

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

提供了

map[key] = value以简化语法。它更容易读写。

需要使用默认构造函数的原因是map[key]是在赋值之前求值的。若映射中不存在键,则会创建一个新的键(使用默认构造函数(,并从operator[]返回对它的引用。