94

I have two vectors:

std::vector<int> v1, v2;

// Filling v1
...

And now I need to copy v1 to v2. Is there any reason to prefer

v2 = v1;

to

std::copy (v1.begin(), v1.end(), v2.begin());

(or vice versa)?

Violet Giraffe
  • 32,368
  • 48
  • 194
  • 335

6 Answers6

121

Generally I would strongly prefer v2 = v1:

  1. It is shorter and makes the intent more clear
  2. std::copy won't work if v2 doesn't have the same length as v1 (it won't resize it, so it will retain some of the old elements best case (v2.size() > v1.size() and overwrite some random data used elsewhere in the program worst case
  3. If v1 is about to expire (and you use C++11) you can easily modify it to move the contents
  4. Performancewise assignment is unlikely to be slower then std::copy, since the implementers would probably use std::copy internally, if it gave a performance benefit.

In conclusion, std::copy is less expressive, might do the wrong thing and isn't even faster. So there isn't really any reason to use it here.

devoured elysium
  • 101,373
  • 131
  • 340
  • 557
Grizzly
  • 19,595
  • 4
  • 60
  • 78
  • 16
    Then, what is `std::copy` for? – altroware Jul 06 '15 at 10:27
  • 39
    @altroware: It's for general copying from one range to another. You can't, for example, use the assignment operator to copy from a `std::list` to a `std::vector`, or from one portion of a `std::vector` to another portion of the same `std::vector`. – Benjamin Lindley Sep 15 '15 at 18:10
  • 2
    What will happen if v1 was allocated on the stack and gets destructed? Does `v2 = v1` cause elements of v1 to be copied? – James Wierzba Apr 07 '16 at 14:57
  • Which copy mechanism of the element type is called? In this case of `vector`, are the integers copied from one vector to the other with `operator=`, or with `int`'s copy constructor? – Gauthier Nov 09 '16 at 08:33
  • How would you implement operator=, in this case? – jorge saraiva Dec 21 '16 at 20:49
  • 1
    @james operator= Will do a full deep copy. Idiomatic C++ uses value semantics so copying a vector copies all its elements. The exception is if it’s elements are pointers in which case the pointers are copied. After assignment, the vectors are independent. – Ben Oct 24 '21 at 01:26
18

If v2 isn't big enough you'll get a buffer overrun if you use copy as you have.

You can use a back insert iterator which will call push_back on v2. However this could lead to multiple reallocations depending upon how big v1 is.

copy(v1.begin(), v1.end(), back_inserter(v2));

You're better off letting vector manage things correctly. The assignment operator does this, as does vector::assign:

v2.assign(v1.begin(), v1.end());

I have an inkling that the assignment operator is implemented in terms of vector::assign.

Peter Wood
  • 23,859
  • 5
  • 60
  • 99
13

The invocation of std::copy may try to access items beyond the end of the destination vector.

Use assignment.

It's not your job to micro-optimize: that's the library writer's responsibility, and ultimately the compiler's responsibility.

You can make your code arbitrarily fast if it doesn't have to be correct.

In the case of the copy, however, it's rather doubtful whether it even is faster, and it's certainly not correct for the general case.

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
  • 3
    I agree with your statements concerning optimization, but it might be worth pointing out that the more information available to the compiler or the library, the better it can do its job. Member functions of `std::vector` know that they're working on an `std::vector`, and know how it is implemented. `std::copy` doesn't have this information. The conclusion is that the member functions can probably do the job better (and certainly not worse). – James Kanze Feb 20 '13 at 10:38
2

It's shorter.

std::copy is mainly meant for copying sections of containers. If you need to copy an entire container, you might as well use the copy constructor.

Symaxion
  • 785
  • 7
  • 21
2

Assignment, by far. More generally, any time the size of the vector might change, or change the entire contents of the vector, you should prefer member functions. The only time std::copy would be appropriate is if you are only replacing a small range totally within the vector.

James Kanze
  • 150,581
  • 18
  • 184
  • 329
1

Assignement is clearer and internally uses std::copy (or unitizalized_copy _M_allocate_and_copy depending size and capacity) or so performances are the same.

FredericS
  • 413
  • 4
  • 9