user360907
user360907

Reputation:

Recycling an unused vector

I've defined a vector in my program as follows:

vector<bool> isPrime (limit + 1, false);

where limit is an int. Later on in the program, I want to recycle the vector, keeping the name but reducing the size and populating all elements with false.

I've tried using

vector<bool> isPrime (otherLimit + 1, false);

in the same way one would redefine an int, char or string, but that returns an error, and since I didn't instantiate it with the new operator, I can't delete the old one. I've been able to manually resize it and and convert each element to false using a for loop, but that seems rather clunky to me.

Is there an easier way to recycle a vector? My desire is to keep the name the same throughout for readability purposes.

Upvotes: 0

Views: 727

Answers (6)

Konrad Rudolph
Konrad Rudolph

Reputation: 545923

You can reset the vector using assignment, just as you’d do for int etc.

Alternatively, you can use the resize method.

Finally, I’d advise against all these approaches: do not recycle variable names. Use variables for one purpose only. Use a new name for a new variable.

Think of a variable name as identifying exactly one entity. The variable name binds the entity to the current scope (and thus, to existence). To create a new entity, always create a new variable name, or a new scope.

Upvotes: 1

Thomas Russell
Thomas Russell

Reputation: 5980

You can use the copy assignment operator, and if you wish to reduce the space consumption you can use the member function shrink_to_fit():

isPrime = vector<bool>(otherLimit+1, false);
isPrime.shrink_to_fit()

Or if you're using C++0x, the move assignment operator:

isPrime = std::move(vector<bool>(otherLimit+1, false));

EDIT: As David pointed out, the compiler will identify the temporary as an rvalue and use rvalue references anyway, so the std::move is unnecessary, the following will be sufficient (and conveniently compatible with both C++03 and C++0x compilers, although move assignment will only be invoked in C++0x):

isPrime = vector<bool>(otherLimit+1, false);

These will both resize your vector and set all elements to false, but if you have access to it, using the move assignment operator will be more efficient.

Also, if you are using a C++03-only compiler, then using Davids .swap() idiom would be more efficient than a copy-assignment in this case.

Hope this helps!

EDIT: In response to David's post: http://ideone.com/wB77w

Upvotes: 2

There are a couple of answers suggesting assignment as in:

isPrime = std::vector<bool>(otherLimit+1,false);

While that solution will work, it might not be exactly what you want. I would suggest that you use the swap-to-resize trick:

std::vector<bool>(otherLimit+1,false).swap( isPrime );

The advantage is that the memory will shrink-to-fit otherLimit+1 elements, and they will be set to false only once. In the assignment case, first otherLimit+1 elements are created and set to false on the right hand side, and then those values are copied over the left hand side isPrime vector... (I don't remember off the top of my head if the operation will shrink the vector, but I doubt so, and that means that the capacity() of isPrime would be std::max( limit+1, otherLimit+1 ))

Upvotes: 1

Simon
Simon

Reputation: 1504

Use std::vector<..>::resize(..) to resize it and std::fill(..) to set a specific value to all elements.

Upvotes: 0

Nicolas Grebille
Nicolas Grebille

Reputation: 1332

Use the assignment (=) operator instead of the constructor:

isPrime = std::vector <bool> (otherLimit + 1, false)

Upvotes: 0

carlpett
carlpett

Reputation: 12613

You could either

isPrime = vector<bool>(otherLimit + 1, false)

or use it's members clear and resize:

isPrime.clear();
isPrime.resize(otherLimit + 1, false);

Upvotes: 5

Related Questions