调用std :: map的operator []或插入时发生了什么 [英] What happened when call std::map's operator[] or insert

查看:146
本文介绍了调用std :: map的operator []或插入时发生了什么的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下代码:

#include <functional>   // std::less
#include <map>
#include <iostream>
using namespace std;

class Key
{
public:
        Key() {cout << "Key Constructor" << endl;}
        ~Key() {cout << "Key Destructor" << endl;}
        Key(const Key& key) {cout << "Key Copy Constructor" << endl;}

        bool operator < (const Key& k1) {return true;}
};
int main()
{
        map<Key, int> mymap;
        Key k;

        cout << "operator[]"<<endl;
        mymap[k] = 1;

        map<Key, int> mymap2;
        cout << "insert"<<endl;
        mymap2.insert(std::make_pair(k, 1));
        cout << "=========" << endl;

}

输出为:

$ g++ test.cpp -fpermissive
$ ./a.out
Key Constructor
operator[]
Key Copy Constructor
Key Copy Constructor
Key Destructor
insert
Key Copy Constructor
Key Copy Constructor
Key Copy Constructor
Key Copy Constructor
Key Destructor
Key Destructor
Key Destructor
=========
Key Destructor
Key Destructor
Key Destructor

任何人都可以解释为什么mymap [k] = 1;调用2个副本构造函数和mymap2.insert(std :: make_pair(k,1));调用4复制构造函数?这是否意味着operator []比insert更有效率?

Could anyone please explain why mymap[k] = 1; invoke 2 copy constructor and mymap2.insert(std::make_pair(k, 1)); invokes 4 copy constructor? and does that mean operator[] is much more efficient than insert?

谢谢.

摘要:

感谢用户6502和petersohn的见识,我现在猜测插入2个额外副本构造函数的原因如下:

Thanks user 6502 and petersohn for your insight, I now guess the reason for the 2 extra copy constructor for insert is as below:

  • make_pair 是一个函数,它在函数内部进行复制首先,然后返回副本-那是一个额外的副本
  • make_pair(k,1)将创建一个pair<Key, int>,但是必需的 value_type pair<const& Key, int>,类型转换将导致另一个额外的副本
  • make_pair is a function, it make a copy inside function first, and then return the copy - that is one extra copy
  • make_pair(k, 1) will create a pair<Key, int>, but the required value_type is pair<const& Key, int>, the type conversion will cause another extra copy

所以在情况2中,如果我使用:

So in case 2, if I use:

mymap2.insert(std::pair<const Key, int>(k, 1));

被调用的拷贝构造函数的数量与operator []相同

The number of copy constructors get called will be the same with operator[]

如6502所述,声明已更改因此不再是真的:

As 6502 noted, following claim has been changed hence not true anymore:

对此函数(operator [])的调用等效于: (*(((this-> insert(make_pair(x,mapped_type()))).first)).second

A call to this function(operator[]) is equivalent to: (*((this->insert(make_pair(x,mapped_type()))).first)).second

operator []的实现方式有所不同,以避免make_pair()引入额外的副本

operator[] is implemented different to avoid extra copy introduced by make_pair()

推荐答案

insert的问题是make_pair将创建一对错误的类型,因此传递的对象将需要转换为正确的对类型才能传递到insert.

The problem with insert is that make_pair will create a pair of the wrong type so the passed object will need a conversion to a proper pair type to be passed to insert.

实际上,在以前的版本中,C ++标准要求map::operator[]表现为insert(因此强制实施效率低下).后来,文本放松了,可以更好地实施.

Actually in a former version the C++ standard mandated map::operator[] to behave as insert (thus forcing an inefficient implementation). Later the text was relaxed allowing a better implementation.

无论如何,请注意,对于标准容器,该元素被视为值",即该实现可以自由复制内容,并且无法保证将复制多少个对象.

Note anyway that for standard containers the elements are considered to be "values", i.e. the implementation is free to copy things around and you get no guarantees about how many copies will be made.

通过将代码更改为

    mymap2.insert(std::pair<const Key, int>(k, 1));

更长的解释

问题在于make_pair将创建一个std::pair<Key, int>值,但insert签名却需要一个const std::pair<const Key, int>&(请注意,std::map::value_type是具有const第一个元素的一对).

Longer explanation

The problem is that make_pair will create an std::pair<Key, int> value but insert signature wants instead a const std::pair<const Key, int>& (note that std::map::value_type is a pair with a const first element).

这两种类型是不兼容且不相关的,因此为了能够进行呼叫,必须创建同时复制键和值的另一对,这是发生额外的键重复的地方.

These two types are incompatible and unrelated so to be able to make the call another pair must be created copying both key and value and this is where an extra key duplication occurs.

即使在显然期望pair<const X, Y>的地方可以直接使用pair<X, Y>显然是逻辑上的",在C ++中也不是正确的,这也是const正确性概念的逻辑问题之一(它不会t按组成比例缩放.

Even if it could be apparently "logical" that a pair<X, Y> should be directly usable where pair<const X, Y> is expected this is not true in C++ and it's one of the logical problems of the const-correctness concept (it doesn't scale by composition).

这篇关于调用std :: map的operator []或插入时发生了什么的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆