using operator[] or insert in map ?

  • Thread starter subramanian100in
  • Start date
S

subramanian100in

For inserting a key-value pair into a map, should I use operator[] or
insert on map ?
Which is more efficient ?

For example consider the following program:

#include <cstdlib>
#include <iostream>
#include <map>

using namespace std;

class Second
{
public:
Second();
Second(const Second& ref);
Second& operator=(const Second& rhs);
inline void value(int arg);
inline int value() const;

private:
int val;
};

Second::Second()
{
cout << "Second default ctor called" << endl;
}

Second::Second(const Second& ref)
{
cout << "Second copy ctor called" << endl;
val = ref.val;
}

Second& Second::eek:perator=(const Second& rhs)
{
cout << "Second operator= called" << endl;

if (this != &rhs)
{
val = rhs.val;
}

return *this;
}

inline void Second::value(int arg)
{
val = arg;
}

inline int Second::value() const
{
return val;
}

int main()
{
Second obj;
obj.value(100);

map<int, Second> m;
cout << "inserting map element in main()" << endl;
cout << "------------------------------" << endl;

m[1] = obj;

obj.value(200);
cout << "------------------------" << endl;
cout << "calling insert from main" << endl;
cout << "------------------------" << endl;

m.insert(map<int,Second>::value_type(2,obj));

return EXIT_SUCCESS;
}

I compiled this program with g++ 3.4.3 as
g++ -std=c++98 -pedantic -Wall -Wextra x.cpp

The output of this program is
Second default ctor called
inserting map element in main()
------------------------------
Second default ctor called
Second copy ctor called
Second copy ctor called
Second operator= called
------------------------
calling insert from main
------------------------
Second copy ctor called
Second copy ctor called

Here, the statement
m[1] = obj;
gives rise to the display of

Second default ctor called
Second copy ctor called
Second copy ctor called
Second operator= called

The statement
m.insert(map<int,Second>::value_type(2,obj));
gives rise to the display of

Second copy ctor called
Second copy ctor called

ie map<int, Second>::eek:perator[] calls one default ctor and assignment
operator corresponding to the mapped value in addition to the two copy
ctor calls which get called for both map<int, Second>::eek:perator[] and
map<int, Second>::insert().

From this, can we conclude that for inserting an element, insert()
member function should be preferred over operator[] ? Will this be the
case with all implementations ? What does the standard say regarding
this ?

Kindly explain

Thanks
V.Subramanian
 
T

Triple-DES

From this, can we conclude that for inserting an element, insert()
member function should be preferred over operator[] ? Will this be the
case with all implementations ? What does the standard say regarding
this ?

The standard says that the map operator[] is eqv. to
(*((insert(make_pair(x, T()))).first)).second (23.3.1.2/1)

And this is exactly how it is implemented in the map implementations I
have seen. (Usually with a temporary iterator)

It is obvious that, for insertion of new elements:
insert(make_pair(x, t))
is more efficient than
(*((insert(make_pair(x, T()))).first)).second = t
 
A

AnonMail2005

For inserting a key-value pair into a map, should I use operator[] or
insert on map ?
Which is more efficient ?

For example consider the following program:

#include <cstdlib>
#include <iostream>
#include <map>

using namespace std;

class Second
{
public:
Second();
Second(const Second& ref);
Second& operator=(const Second& rhs);
inline void value(int arg);
inline int value() const;

private:
int val;

};

Second::Second()
{
        cout << "Second default ctor called" << endl;

}

Second::Second(const Second& ref)
{
        cout << "Second copy ctor called" << endl;
        val = ref.val;

}

Second& Second::eek:perator=(const Second& rhs)
{
        cout << "Second operator= called" << endl;

        if (this != &rhs)
        {
                val = rhs.val;
        }

        return *this;

}

inline void Second::value(int arg)
{
        val = arg;

}

inline int Second::value() const
{
        return val;

}

int main()
{
        Second obj;
        obj.value(100);

        map<int, Second> m;
        cout << "inserting map element in main()" << endl;
        cout << "------------------------------" << endl;

        m[1] = obj;

        obj.value(200);
        cout << "------------------------" << endl;
        cout << "calling insert from main" << endl;
        cout << "------------------------" << endl;

        m.insert(map<int,Second>::value_type(2,obj));

        return EXIT_SUCCESS;

}

I compiled this program with g++ 3.4.3 as
g++ -std=c++98 -pedantic -Wall -Wextra x.cpp

The output of this program is
Second default ctor called
inserting map element in main()
------------------------------
Second default ctor called
Second copy ctor called
Second copy ctor called
Second operator= called
------------------------
calling insert from main
------------------------
Second copy ctor called
Second copy ctor called

Here, the statement
       m[1] = obj;
gives rise to the display of

Second default ctor called
Second copy ctor called
Second copy ctor called
Second operator= called

The statement
        m.insert(map<int,Second>::value_type(2,obj));
gives rise to the display of

Second copy ctor called
Second copy ctor called

ie map<int, Second>::eek:perator[] calls one default ctor and assignment
operator corresponding to the mapped value in addition to the two copy
ctor calls which get called for both map<int, Second>::eek:perator[] and
map<int, Second>::insert().

From this, can we conclude that for inserting an element, insert()
member function should be preferred over operator[] ? Will this be the
case with all implementations ? What does the standard say regarding
this ?

Kindly explain

Thanks
V.Subramanian

The below post by Triple-DES is correct. If it's not obvious, the
code
below first inserts a default constructed instance of object T and
then
assigns the actual object that you want. This is extra work than just
inserting the object that you want.

For more explanation and motivation via examples, check out Effective
STL by Meyers.

HTH
 
J

James Kanze

For inserting a key-value pair into a map, should I use operator[] or
insert on map ?

They don't have the same semantics; you use the one which has
the desired semantics.
Which is more efficient ?

The one that does what you want. Since the semantics are
different, you can't compare them for efficiency. You can't
replace one with the other anyway.

If you're inserting a key-value pair, obviously, you use insert,
because operator[] won't do what you want. If you want to
ensure that the value for a specific key has a specific value,
you use [] and assignment, because insert won't do what you
want.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,930
Messages
2,570,072
Members
46,522
Latest member
Mad-Ram

Latest Threads

Top