私は次のコードを持っています:
#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[] が挿入よりもはるかに効率的であることを意味しますか?
ありがとう。
概要:
ユーザー 6502 と petersohn の洞察に感謝します。挿入用の 2 つの余分なコピー コンストラクターの理由は次のとおりだと思います。
- make_pairは関数です。最初に関数内でコピーを作成し、次にそのコピーを返します。これは 1 つの余分なコピーです。
- 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() によって導入される余分なコピーを避けるために、別の方法で実装されています。