Roddy
Roddy

Reputation: 68033

How to resize std::vector with unique objects

I have a vector of objects. Each object has a boost::shared_ptr to a noncopyable object (a boost::signal). the object's default constructor creates the boost::signal object.

struct FuncRef
{
    typedef boost::signal0<void, > Func;
    boost::shared_ptr <Func> function;
    FuncRef():
        function(new Func)
    {
    }
};

To set my vector to contain X individual objects, I did this:-

vec.resize(X);

This didn't do what I expected, because it uses the default constructor to make one object, and then the copy constructor to make the duplicates. I end up with X objects, but they all point to the same boost::signal0 object.

Is there an easier way of building my vector correctly than just using push_back in a for loop?

Upvotes: 3

Views: 1822

Answers (3)

Mark B
Mark B

Reputation: 96241

Are you not able to implement a copy constructor/copy assignment with actual copy semantics? Unless you're having serious performance with the vector filling this seems like the most obvious solution.

Upvotes: 0

Bj&#246;rn Pollex
Bj&#246;rn Pollex

Reputation: 76788

The only way I can think of is to use reserve to make the vector allocate the memory you need (as @Jonathan answered). You can the use generate_n with an std::back_inserter to add the elements:

FuncRef makeFuncRef() {
    return FuncRef();
}

vec.reserve(vec.size() + n);
std::generate(std::back_inserter(vec), n, makeFuncRef);

The reserve is not necessary with this approach, although it is probably faster if n is large.

Upvotes: 3

Jonathan Grynspan
Jonathan Grynspan

Reputation: 43472

The simplest way I can think of is to reserve the memory beforehand so that only one allocation is needed by the vector:

vec.reserve(X);

Then loop and push_back(). Is that not sufficient for your needs?

Upvotes: 1

Related Questions