我有以下代码:

#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更有效?

谢谢。

摘要:

感谢用户6502和petersohn的见识,我现在推测插入2个额外副本构造函数的原因如下:
  • make_pair是一个函数,它首先在函数内部创建一个副本,然后返回该副本-这是一个额外的副本
  • make_pair(k,1)将创建一个pair<Key, int>,但是所需的value_typepair<const& Key, int>,类型转换将导致另一个额外的副本

  • 因此,在情况2中,如果我使用:
    mymap2.insert(std::pair<const Key, int>(k, 1));
    

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

    如6502所述,以下claim已更改,因此不再适用:



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

    最佳答案

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

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

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

    您可以通过将代码更改为来查看make_pair问题

        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第一个元素的对)。

    这两种类型是不兼容且不相关的,因此要能够进行 call ,必须创建另一个复制 key 和值的对,这是发生额外 key 重复的地方。

    即使在期望pair<X, Y>的地方应该直接使用pair<const X, Y>显然是“逻辑上的”,在C++中也不是正确的,这是const-正确性概念的逻辑问题之一(它不能按组成比例缩放)。

    关于c++ - 调用std::map运算符[]或插入时会发生什么,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17247998/

    10-11 00:57
    查看更多