M
Mark P
Consider the following:
// Contrast different ways of inserting into a map
#include <map>
#include <iostream>
using namespace std;
struct A
{
A () {cout << "ctor\n";}
A (const A& a) {cout << "copy ctor\n";}
A& operator= (const A& a) {cout << "op=\n"; return *this;}
};
typedef map<int,A> IAMap;
typedef IAMap::value_type IAMVal;
int main()
{
cout << "\nm1[0] = ...\n";
IAMap m1;
m1[0] = A();
cout << "\nm2.insert(IAMVal...)\n";
IAMap m2;
m2.insert(IAMVal(0,A()));
}
// end of code
The output is:
m1[0] = ...
ctor
copy ctor
copy ctor
ctor
op=
m2.insert(IAMVal...)
ctor
copy ctor
copy ctor
// end of output
First of all, are the two copy ctor calls both necessary? I gather that
one occurs when constructing the temporary IAMVal and a second occurs
when copying that temporary into the map. Can a smart compiler
eliminate (elide?) the construction of the temporary? (My version of
gcc with maximum optimiztion will not do so.)
On a related note, in Scott Meyers's "Effective STL" he compares these
two approaches in the contexts of inserts (new key) vs. updates
(existing key with new data). He states about inserts, "Efficiency
considerations thus lead us to conclude that insert is preferable to
operator[] when adding an element to a map..." And so it would appear
by simply counting the number of operations above.
But now suppose my data type contains a vector which is empty for a
default constructed object and I want to insert an object whose vector
isn't empty. Comparing the two approaches and paying attention only to
operations which involve the nonempty vector (since this is ostensibly
more work), the insert approach involves two copies of the nonempty
vector while the [] appraoch involves only one assignment of the
nonempty vector. (Unless of course the compiler can eliminate one of
the copies.) Am I looking at this right?
Thanks,
Mark
// Contrast different ways of inserting into a map
#include <map>
#include <iostream>
using namespace std;
struct A
{
A () {cout << "ctor\n";}
A (const A& a) {cout << "copy ctor\n";}
A& operator= (const A& a) {cout << "op=\n"; return *this;}
};
typedef map<int,A> IAMap;
typedef IAMap::value_type IAMVal;
int main()
{
cout << "\nm1[0] = ...\n";
IAMap m1;
m1[0] = A();
cout << "\nm2.insert(IAMVal...)\n";
IAMap m2;
m2.insert(IAMVal(0,A()));
}
// end of code
The output is:
m1[0] = ...
ctor
copy ctor
copy ctor
ctor
op=
m2.insert(IAMVal...)
ctor
copy ctor
copy ctor
// end of output
First of all, are the two copy ctor calls both necessary? I gather that
one occurs when constructing the temporary IAMVal and a second occurs
when copying that temporary into the map. Can a smart compiler
eliminate (elide?) the construction of the temporary? (My version of
gcc with maximum optimiztion will not do so.)
On a related note, in Scott Meyers's "Effective STL" he compares these
two approaches in the contexts of inserts (new key) vs. updates
(existing key with new data). He states about inserts, "Efficiency
considerations thus lead us to conclude that insert is preferable to
operator[] when adding an element to a map..." And so it would appear
by simply counting the number of operations above.
But now suppose my data type contains a vector which is empty for a
default constructed object and I want to insert an object whose vector
isn't empty. Comparing the two approaches and paying attention only to
operations which involve the nonempty vector (since this is ostensibly
more work), the insert approach involves two copies of the nonempty
vector while the [] appraoch involves only one assignment of the
nonempty vector. (Unless of course the compiler can eliminate one of
the copies.) Am I looking at this right?
Thanks,
Mark