建议将元素插入地图的方法

Che*_*eng 91 c++ stl stdmap

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

我想知道,当我将元素插入地图时,建议的方法是什么.我是不是该

map[key] = value;
Run Code Online (Sandbox Code Playgroud)

要么

map.insert(std::pair<key_type, value_type>(key, value));
Run Code Online (Sandbox Code Playgroud)

我做了以下快速测试:

#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");
}
Run Code Online (Sandbox Code Playgroud)
  1. 我通过使用成员函数实现,insert将涉及较少值的函数调用.那么,是使用insert推荐的方式?
  2. 当使用map[key] = value方式时,为什么需要默认构造函数?

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

怎么样

  1. 性能
  2. 值的默认构造函数的可用性
  3. ???

BЈо*_*вић 64

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

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

  • 这没有提到最重要的区别,如果元素已经存在,则insert不会执行任何操作. (13认同)

Jam*_*nze 45

使用insert,如果要插入一个新元素. insert不会覆盖现有元素,您可以验证以前没有exing元素:

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

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

myMap[ key ] = value;
assert( myMap.find( key )->second == value ); // post-condition
Run Code Online (Sandbox Code Playgroud)

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


Luc*_*ore 13

报价:

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

因此,如果密钥已存在,则插入不会更改值[] operator.

编辑:

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

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


x13*_*13n 9

map[key] = value提供更简单的语法.它更易于阅读和书写.

您需要具有默认构造函数的原因map[key]是在赋值之前进行评估.如果map中没有key,则创建一个新的(使用默认构造函数)并从中返回对它的引用operator[].

  • 这不仅仅是语法。当映射已包含“key”的值时,“map[key] = value;”和“map.insert({key,value});”不同 (2认同)