I've learnt that operator[] is equivalent to
(*((this->insert(make_pair(k,mapped_type()))).first)).second
So if a key doesn't exist in the map, using operator[] is less efficient than using insert, right? Because there's one more step, default construct.
So I wrote a demo to test, like this.
#include <iostream>
#include <map>
using namespace std;
static int id = 0;
class Foo
{
public:
Foo()
: _val(0)
{
_id = ++id;
cout << _id << " construct_no_param:" << _val << endl;
}
Foo(int val)
: _val(val)
{
_id = ++id;
cout << _id << " construct_has_param:" << _val << endl;
}
Foo(Foo &rhs)
: _val(rhs._val)
{
_id = ++id;
cout << _id << " construct_copy:" << _val << endl;
}
Foo(const Foo &rhs)
: _val(rhs._val)
{
_id = ++id;
cout << _id << " construct_const_copy:" << _val << endl;
}
Foo &operator=(Foo &rhs)
{
_val = rhs._val;
cout << _id << " assign:" << _val << endl;
}
Foo &operator=(const Foo &rhs)
{
_val = rhs._val;
cout << _id << " const_assign:" << _val << endl;
}
~Foo()
{
cout << _id << " destruct:" << _val << endl;
}
int _val;
int _id;
};
int main() {
map<int, Foo> m;
const Foo f(2);
cout << "-----" << endl;
// m[1] = f;
// m.insert(make_pair(1, f));
cout << "-----" << endl;
return 0;
}
First, I used operator[]
m[1] = f;
And I got this:
1 construct_has_param:2
-----
2 construct_no_param:0
3 construct_const_copy:0
4 construct_const_copy:0
3 destruct:0
2 destruct:0
4 assign:2
-----
1 destruct:2
4 destruct:2
Then, I used insert
m.insert(make_pair(1, f));
And I got this:
1 construct_has_param:2
-----
2 construct_const_copy:2
3 construct_const_copy:2
4 construct_const_copy:2
5 construct_const_copy:2
4 destruct:2
3 destruct:2
2 destruct:2
-----
1 destruct:2
5 destruct:2
The results are not correspond to what I'm expected. Why insert has more constructions? What's going on here?
BTW, I use -O0 option to disable optimization, but I'm not sure if it works.
gcc version 4.8.2 20131212 (Red Hat 4.8.2-8) (GCC)