RegEx
RegEx

Reputation: 125

What's difference between those two std::vector's assign methods?

There are two ways (that I know) of assigning one vector to another:

std::vector<std:string> vectorOne, vectorTwo;
// fill vectorOne with strings

// First assign method
vectorTwo = vectorOne;

// Second assign method
vectorTwo.assign( vectorOne.begin(), vectorOne.end() );

Is there really difference within those methods or they are equal in terms of efficiency and safety when performed on very big vectors?

Upvotes: 4

Views: 2790

Answers (3)

4pie0
4pie0

Reputation: 29734

They are equivalent in this case. [and C++03 standaerd]. The difference will be however if vectorTwo contains elements before assignment. Then

vectorTwo = vectorOne; // use operator=
// Any elements held in the container before the call 
// are either assigned to or destroyed.

vectorTwo.assign() // any elements held in the container
// before the call are destroyed and replaced by newly 
// constructed elements (no assignments of elements take place).

assign is needed because operator= takes single right-hand operand so assign is used when there is a need for a default argument value or range of values. What assign does could be done indirectly by first creating suitable vector and then assigning that:

void f(vector<Book>& v, list<Book>& l){
    vector<Book> vt = (l.begin(), l.end());
    v = vt;
}

however this can be both ugly and inefficient (example has been taken from Bjarne Stroustrup "The C++...")

Also note that if vector is not of the same type then there is also need for assign which allows implicit conversion:

vector<int> vi;
vector<double> vd;
//  ...
vd.assign( vi.begin(), vi.end() );

Upvotes: 1

Jonathan Wakely
Jonathan Wakely

Reputation: 171373

The second form is generic, it works with any iterator types, and just copies the elements from the source vector.

The first form only works with exactly the same type of vector, it copies the elements and in C++11 might also replace the allocator by copying the allocator from the source vector.

In your example the types are identical, and use std::allocator which is stateless, so there is no difference. You should use the first form because it's simpler and easier to read.

Upvotes: 7

James Kanze
James Kanze

Reputation: 153977

They're pretty much equivalent. The reason for the second is that you might have types which need (implicit) conversion:

std::vector<int> vi;
std::vector<double> vd;
//  ...
vd.assign( vi.begin(), vi.end() );

Or the type of the container might be different:

vd.assign( std::istream_iterator<double>( file ),
           std::istream_iterator<double>() );

If you know that both of the containers are the same type, just use assignment. It has the advantage of only using a single reference to the source, and possibly allowing move semantics in C++11.

Upvotes: 8

Related Questions