Q-bertsuit
Q-bertsuit

Reputation: 3437

copy algorithm vs. container constructor

What advantages if any does the copy algorithm have over using the constructor of a container directly?

This example is from cplusplus.com:

// copy algorithm example
#include <iostream>     // std::cout
#include <algorithm>    // std::copy
#include <vector>       // std::vector

int main () {
  int myints[]={10,20,30,40,50,60,70};
  std::vector<int> myvector (7);

  std::copy ( myints, myints+7, myvector.begin() );

  std::cout << "myvector contains:";
  for (std::vector<int>::iterator it = myvector.begin(); it!=myvector.end(); ++it)
    std::cout << ' ' << *it;

  std::cout << '\n';

  return 0;
}

Why should the copy approach be preferred to

std::vector<int> myvector(myints, myints+7);

Upvotes: 0

Views: 171

Answers (3)

LihO
LihO

Reputation: 42083

Well, firstly, since you are using C++11:

int myints[]={10,20,30,40,50,60,70};
std::vector<int> myvector(myints, myints+7);

for (std::vector<int>::iterator it = myvector.begin(); it!=myvector.end(); ++it)
    std::cout << ' ' << *it;

could actually be written the following way:

std::vector<int> myVector = {10,20,30,40,50,60,70};

for (const int i : myVector )
    std::cout << ' ' << i;
Secondly, you are comparing:
  • direct construction of vector using iterators vs.
  • construction of vector, elements of which are going to be overwritten using std::copy.
If you want to construct a vector using C-style array / iterators, then:
std::vector<int> myVector(myints, myints+7);
If you want to build another vector using existing one, then one of the following:
std::vector<int> myVector2(myVector);
std::vector<int> myVector3 = myVector;  // invokes copy constructor anyway...
If you have 2 vectors already and you want to overwrite one with another, then:
myVector2 = myVector;

... just don't optimize prematurely and let your code reflect your purpose.

Upvotes: 2

Johan
Johan

Reputation: 3778

It's not useful for building a new container because most of the time the container itself can take iterators

You may have to use it if you're working with raw arrays. E.g.:

std::vector<int> my_vect;
int* array_for_a_low_level_lib = new int[my_vect.size()];
std::copy(std::begin(my_vect), std::end(my_vect), array_for_a_low_level_lib);

Here are two of my favorites usage examples, adding iterator header:

template <typename InnerType, typename Container>
void fill_container(Container& cont)
{
  std::copy(std::istream_iterator<InnerType>(std::cin), 
            std::istream_iterator<InnerType>(), 
            std::inserter(cont, cont.end()));
}

template <typename InnerType, typename Container>
void print_container(const Container& cont)
{
  std::copy(std::begin(cont), std::end(cont), 
    std::ostream_iterator<InnerType>(std::cout, " "));
}

http://ideone.com/4MOhSE

Also used with boost::range adapters you can do beautiful things, like filling vectors from maps in one quite readable line.

Upvotes: 1

Zac Howland
Zac Howland

Reputation: 15872

This is an example of a poor example on cplusplus.com. If you had such an array and were really going to copy it into a vector, you would use the constructor. std::copy is useful in many other ways (e.g. if you wanted to output the array to a file or the console), but construction is not one of them.

Upvotes: 4

Related Questions