Reputation: 125
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
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
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
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