C ++ STL container and construction in place

Please note the following:

class CMyClass { public: CMyClass() { printf( "Constructor\n" ); } CMyClass( const CMyClass& ) { printf( "Copy constructor\n" ); } }; int main() { std::list<CMyClass> listMyClass; listMyClass.resize( 1 ); return 0; } 

It produces the following output:

Constructor

Copy constructor

Now my question is: how to avoid copy constructor? Or in another way: how can I create objects inside an STL container without an unnecessary copy operation. Is there a way to make the construction in place using the default constructor?


Update - answers so far:

  • It is impossible to do
  • Use pointers or smart pointers instead.

Smart pointers are redundant for my application. But I really wonder why this cannot be done. This seems like such an obvious thing to do. Any other ideas? I will even accept a nasty hack if it works ...


Decision

I think I found a solution to my problem from all the comments and answers given here. The solution is to create an empty object and save it for the sole purpose of using it later to create clean copies. Then you can use one of the methods that accept the link (for example, push_back or insert). This still calls the copy constructor for each inserted new object, but at least it is not the constructor of the AND constructor and the default constructor:

 int main() { CMyClass Empty; std::list<CMyClass> listMyClass; for ( int c=0; c<10; ++c ) { listMyClass.push_back( Empty ); } return 0; } 
+6
c ++ stl
source share
7 answers

By design, all containers in the C ++ standard library store copies. Therefore, calling the copy constructor cannot be avoided if you want to store values ​​in a container - the only way out is to save pointers instead. If you want to reduce copying overhead, consider using reference counting.

+8
source share

use pointers

 std::list<CMyClass*> listMyClass; 
+1
source share

Sorry, not currently with std :: list and similar containers. (But you can write your own slightly different container if you really need it, and still follow the rest of the STL interface.)

However, you do not need to use ctor by default:

 std::list<CMyClass> listMyClass; listMyClass.resize(1, obj_to_copy_from); 

For example:

 std::list<CMyClass> listMyClass; listMyClass.resize(1, CMyClass(use, specific, ctor)); 

Resizing is as follows:

 void list<T>::resize(size_type new_size, T copy_from = T()); 

By default, a new object is created (using ctor by default).

+1
source share

It would be useful if the vector allowed the initialization of new elements with a standard constructor when resizing due to performance, but this is not supported. If you really need it, create a custom container - there will be no other way.

+1
source share

use a pointer or smart pointer (boost :: shared_ptr, not auto_ptr)

0
source share

http://swagatata.tumblr.com/post/5896332725/vector-construction

Even if you do

 std::list<classname> objectname(100); 

the constructor will be called once, and 100 objects will be constructed using the copy constructor.

0
source share

you can do in c11, for older versions, vesry simple can be improved

vector

 myclas: public vector<A> { push_back(Aconstructor_parameters) { new(_Mylast++) A(Aconstructor_parameters); } }; 

when using, make sure you use reserve() to allocate memory

0
source share

All Articles