tags:

views:

110

answers:

3

I particularly like the simplicity of using STL containers in the straightforward way.

I have never really figured out how to get the Boost library working on my dev platforms, in fact I don't think I've even tried. I guess you could say I am just trying to delay the inevitable since Boost is clearly a helpful library that I should be using.

But my question is essentially the same as this topic: http://stackoverflow.com/questions/2580189/how-to-initialise-a-stl-vector-list-with-a-class-without-invoking-the-copy-constr

I have std::list<ExpensiveClass> mylist; and I just want a function that pushes a new instance into the list and calls the default constructor, rather than copying it from a temporary stack instance of it. In the other topic there was mention of move constructors. I looked them up and quite frankly it does nothing but strike fear into my heart. Two ampersands!!

Would it work if I just made an array of ExpensiveClass objects? ExpensiveClass *mylist = new ExpensiveClass[20]; Does this call the constructor 20 times?

Seems to me I should just use boost:ptr_list.

+7  A: 

Inserting an object into a container invokes the copy constructor on that object. There's really no way around that (yet), hence why pointer containers are used for large objects: it's dirt cheap to copy a pointer.

If you choose to use a container of smart pointers, you can either use one of the Boost pointer containers or you can use an STL container of shared_ptrs.

To answer your question about:

ExpensiveClass *mylist = new ExpensiveClass[20];

The default constructor for ExpensiveClass is called 20 times: once for each element of the array.

James McNellis
+1 regarding using `shared_ptr`. I've generally avoided Boost, but the TR1 `shared_ptr` is incredibly useful for this kind of problem without requiring you to pull in Boost.
Rob Napier
Great answer. Thanks!
Steven Lu
If your implementation has partial support for C++0x (both g++ and MSVC do), consider using `std::unique_ptr` over `std::shared_ptr` - it's more efficient (should be identical to Boost `ptr_...` containers), and represents the intended semantics more precisely.
Pavel Minaev
+2  A: 

I just want a function that pushes a new instance into the list and calls the default constructor

Since you mentioned "two ampersands", I am going to give you the C++0x solution:

mylist.emplace_back();

If you want to use a different constructor, simply provide arguments:

mylist.emplace_back(whatever, arguments, your, constructor, takes);

This member function constructs the object in-place, without copying (or moving).

FredOverflow
If the OP can take advantage of emplace_back, he should definitely use that. In your first example, the default constructor is called once and then that default constructed object is copied twenty times (using the copy constructor, obviously). Someone else had suggested this in a now-deleted answer, and the OP had indicated he was trying to avoid calling the copy constructor (that's just a heads-up for any non-10kers who can't see the deleted answer).
James McNellis
@James: Ooops, I removed that part of my answer, thanks :)
FredOverflow
A: 

Depending on implementation support for C++0x features, have a look at emplace_back and similar member functions - they do precisely what you ask for, i.e. construct an object directly inside the container, "in-place", without any copying.

Pavel Minaev