P
Paul Brettschneider
Hello,
I have a use-case where I have a number of objects of a complex class.
Copying is very expensive and should be avoided. I want to access those
objects by ids (std::string objects). A std::map<std::string, MyClass>
object suggests itself but, at least under gcc, it does two gratuitous
copies:
#include <iostream>
#include <map>
#include <string>
class Test {
int x;
public: Test() : x(0) { std::cout << "Default!\n"; };
Test(const Test &t) : x(t.x) { std::cout << "Copy!\n"; };
void test() { std::cout << x << "\n"; }
};
int main()
{
std::map<std::string, Test> test_map;
test_map["hello"].test();
return 0;
}
outputs:
Default!
Copy!
Copy!
0
I suppose the first copy happens at the initialisation of a std:air<key,
value> the second one when the pair is moved into the container proper.
For me it's not obvious why the object couldn't just be created in-place.
Does the standard say anything about this, or is this an QOI issue?
And what is the common way of avoiding this kind of problem?
I've pondered about either using "smart" pointers (i.e. refcounting), or
making the copy constructor aware of the fact that it is copying a freshly
created instance, and use init() function on the object once it is in
place. Both methods seem unnecessarily complicated.
Thanks,
Paul
I have a use-case where I have a number of objects of a complex class.
Copying is very expensive and should be avoided. I want to access those
objects by ids (std::string objects). A std::map<std::string, MyClass>
object suggests itself but, at least under gcc, it does two gratuitous
copies:
#include <iostream>
#include <map>
#include <string>
class Test {
int x;
public: Test() : x(0) { std::cout << "Default!\n"; };
Test(const Test &t) : x(t.x) { std::cout << "Copy!\n"; };
void test() { std::cout << x << "\n"; }
};
int main()
{
std::map<std::string, Test> test_map;
test_map["hello"].test();
return 0;
}
outputs:
Default!
Copy!
Copy!
0
I suppose the first copy happens at the initialisation of a std:air<key,
value> the second one when the pair is moved into the container proper.
For me it's not obvious why the object couldn't just be created in-place.
Does the standard say anything about this, or is this an QOI issue?
And what is the common way of avoiding this kind of problem?
I've pondered about either using "smart" pointers (i.e. refcounting), or
making the copy constructor aware of the fact that it is copying a freshly
created instance, and use init() function on the object once it is in
place. Both methods seem unnecessarily complicated.
Thanks,
Paul