我有以下代码:
#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_type是pair<const& Key, int>
,类型转换会导致另一个额外的副本
因此,在情况 2 中,如果我使用:
mymap2.insert(std::pair<const Key, int>(k, 1));
调用的复制构造函数的数量将与 operator[] 相同
正如 6502 所指出的,以下声明已更改,因此不再正确:
调用此函数(operator[]) 等效于: (*((this->insert(make_pair(x,mapped_type()))).first)).second
operator[] 的实现方式不同,以避免 make_pair() 引入的额外副本