andreas buykx
andreas buykx

Reputation: 12950

How to fill a vector with non-trivial initial values?

I know how to fill an std::vector with non-trivial initial values, e.g. sequence numbers:

void IndexArray( unsigned int length, std::vector<unsigned int>& v )
{
    v.resize(length);
    for ( unsigned int i = 0; i < length; ++i )
    {
        v[i] = i;
    }
}

But this is a for-loop. Is there an elegant way to do this with less lines of code using stl functionality (and not using Boost)?

Upvotes: 15

Views: 10907

Answers (6)

Rick
Rick

Reputation: 709

I know this has already been answered, but I prefer the "fill" function in the algorithm library, since it's seems more intuitive for me to read:

// fill algorithm example
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

int main () {
  vector<int> myvector (8);                       // myvector: 0 0 0 0 0 0 0 0

  fill (myvector.begin(),myvector.begin()+4,5);   // myvector: 5 5 5 5 0 0 0 0
  fill (myvector.begin()+3,myvector.end()-2,8);   // myvector: 5 5 5 8 8 8 0 0

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

  cout << endl;

  return 0;
}

This too was also shamelessly lifted from cplusplusreference.

Upvotes: 1

maccullt
maccullt

Reputation: 2829

If you have a C style array you can use std:copy, e.g.,

int c_array[] = {3,4,5};

const int* pbegin = &c_array[0];
const size_t c_array_size = sizeof(c_array) / sizeof(c_array[0]);
const int* pend  = pbegin + c_array_size;

std::vector<int> v;
v.reserve(c_array_size);
std::copy(pbegin, pend, std:back_inserter(v));

Upvotes: 0

Luc Hermitte
Luc Hermitte

Reputation: 32966

There is also a iota() function in adobe.ASL, (and a value_iterator as well). In boost, there is a counting_iterator, and I suspect a few other ways to do generate number sequences on the fly in boost.

Upvotes: 2

moogs
moogs

Reputation: 8202

You can use the generate algorithm, for a more general way of filling up containers:

#include <iostream>
#include <algorithm>
#include <vector>

struct c_unique {
   int current;
   c_unique() {current=0;}
   int operator()() {return ++current;}
} UniqueNumber;


int main () {
  vector<int> myvector (8);
  generate (myvector.begin(), myvector.end(), UniqueNumber);

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

  cout << endl;

  return 0;
}

This was shamelessly lifted and edited from cplusplusreference.

Upvotes: 15

Konrad Rudolph
Konrad Rudolph

Reputation: 545923

I usually go with std::generate plus a simple generator:

template <typename T>
struct gen {
    T x;
    gen(T seed) : x(seed) { }

    T operator ()() { return x++; }
};

generate(a.begin(), a.end(), gen<int>(0));

Upvotes: 5

C. K. Young
C. K. Young

Reputation: 223133

If you're using SGI STL (or a derivative, such as STLPort), you can use iota. :-)

void IndexArray(unsigned int length, vector<unsigned int>& v)
{
    vector<unsigned int>(length).swap(v);
    iota(v.begin(), v.end(), 0);
}

Upvotes: 4

Related Questions