[c++] use std::fill to populate vector with increasing numbers

I would like to fill a vector<int> using std::fill, but instead of one value, the vector should contain numbers in increasing order after.

I tried achieving this by iterating the third parameter of the function by one, but this would only give me either vectors filled with 1 or 2 (depending of the position of the ++ operator).

Example:

vector<int> ivec;
int i = 0;
std::fill(ivec.begin(), ivec.end(), i++); // elements are set to 1
std::fill(ivec.begin(), ivec.end(), ++i); // elements are set to 2

This question is related to c++ stl

The answer is


Speaking of boost:

auto ivec = boost::copy_range<std::vector<int>>(boost::irange(5, 10));

brainsandwich and underscore_d gave very good ideas. Since to fill is to change content, for_each(), the simplest among the STL algorithms, should also fill the bill:

std::vector<int> v(10);
std::for_each(v.begin(), v.end(), [i=0] (int& x) mutable {x = i++;});    

The generalized capture [i=o] imparts the lambda expression with an invariant and initializes it to a known state (in this case 0). the keyword mutable allows this state to be updated each time lambda is called.

It takes only a slight modification to get a sequence of squares:

std::vector<int> v(10);
std::for_each(v.begin(), v.end(), [i=0] (int& x) mutable {x = i*i; i++;});

To generate R-like seq is no more difficult, but note that in R, the numeric mode is actually double, so there really isn't a need to parametrize the type. Just use double.


If you'd rather not use C++11 features, you can use std::generate:

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

struct Generator {
    Generator() : m_value( 0 ) { }
    int operator()() { return m_value++; }
    int m_value;
};

int main()
{
    std::vector<int> ivec( 10 );

    std::generate( ivec.begin(), ivec.end(), Generator() );

    std::vector<int>::const_iterator it, end = ivec.end();
    for ( it = ivec.begin(); it != end; ++it ) {
        std::cout << *it << std::endl;
    }
}

This program prints 0 to 9.


I created a simple templated function, Sequence(), for generating sequences of numbers. The functionality follows the seq() function in R (link). The nice thing about this function is that it works for generating a variety of number sequences and types.

#include <iostream>
#include <vector>

template <typename T>
std::vector<T> Sequence(T min, T max, T by) {
  size_t n_elements = ((max - min) / by) + 1;
  std::vector<T> vec(n_elements);
  min -= by;
  for (size_t i = 0; i < vec.size(); ++i) {
    min += by;
    vec[i] = min;
  }
  return vec;
}

Example usage:

int main()
{
    auto vec = Sequence(0., 10., 0.5);
    for(auto &v : vec) {
        std::cout << v << std::endl;
    }
}

The only caveat is that all of the numbers should be of the same inferred type. In other words, for doubles or floats, include decimals for all of the inputs, as shown.

Updated: June 14, 2018


I've seen the answers with std::generate but you can also "improve" that by using static variables inside the lambda, instead of declaring a counter outside of the function or creating a generator class :

std::vector<int> vec;
std::generate(vec.begin(), vec.end(), [] {
    static int i = 0;
    return i++;
});

I find it a little more concise


You should use std::iota algorithm (defined in <numeric>):

  std::vector<int> ivec(100);
  std::iota(ivec.begin(), ivec.end(), 0); // ivec will become: [0..99]

Because std::fill just assigns the given fixed value to the elements in the given range [n1,n2). And std::iota fills the given range [n1, n2) with sequentially increasing values, starting with the initial value and then using ++value.You can also use std::generate as an alternative.

Don't forget that std::iota is C++11 STL algorithm. But a lot of modern compilers support it e.g. GCC, Clang and VS2012 : http://msdn.microsoft.com/en-us/library/vstudio/jj651033.aspx

P.S. This function is named after the integer function ? from the programming language APL, and signifies a Greek letter iota. I speculate that originally in APL this odd name was chosen because it resembles an “integer” (even though in mathematics iota is widely used to denote the imaginary part of a complex number).


My first choice (even in C++11) would be boost::counting_iterator :

std::vector<int> ivec( boost::counting_iterator<int>( 0 ),
                       boost::counting_iterator<int>( n ) );

or if the vector was already constructed:

std::copy( boost::counting_iterator<int>( 0 ),
           boost::counting_iterator<int>( ivec.size() ),
           ivec.begin() );

If you can't use Boost: either std::generate (as suggested in other answers), or implement counting_iterator yourself, if you need it in various places. (With Boost, you can use a transform_iterator of a counting_iterator to create all sorts of interesting sequences. Without Boost, you can do a lot of this by hand, either in the form of a generator object type for std::generate, or as something you can plug into a hand written counting iterator.)


Preferably use std::iota like this:

std::vector<int> v(100) ; // vector with 100 ints.
std::iota (std::begin(v), std::end(v), 0); // Fill with 0, 1, ..., 99.

That said, if you don't have any c++11 support (still a real problem where I work), use std::generate like this:

struct IncGenerator {
    int current_;
    IncGenerator (int start) : current_(start) {}
    int operator() () { return current_++; }
};

// ...

std::vector<int> v(100) ; // vector with 100 ints.
IncGenerator g (0);
std::generate( v.begin(), v.end(), g); // Fill with the result of calling g() repeatedly.

this also works

j=0;
for(std::vector<int>::iterator it = myvector.begin() ; it != myvector.end(); ++it){
    *it = j++;
}

In terms of performance you should initialize the vector with use of reserve() combined with push_back() functions like in the example below:

const int numberOfElements = 10;

std::vector<int> data;
data.reserve(numberOfElements);

for(int i = 0; i < numberOfElements; i++)
    data.push_back(i);

All the std::fill, std::generate, etc. are operating on range of existing vector content, and, therefore the vector must be filled with some data earlier. Even doing the following: std::vector<int> data(10); creates a vector with all elements set to its default value (i.e. 0 in case of int).

The above code avoids to initialize vector content before filling it with the data you really want. Performance of this solution is well visible on large data sets.


I know this is old question, but I am currently playing with library to handle exactly this problem. It requires c++14.

#include "htl.hpp"

htl::Token _;

std::vector<int> vec = _[0, _, 100];
// or
for (auto const e: _[0, _, 100]) { ... }

// supports also custom steps
// _[0, _%3, 100] == 0, 4, 7, 10, ...

We can use generate function which exists in algorithm header file.

Code Snippet :

#include<bits/stdc++.h>
using namespace std;


int main()
{
    ios::sync_with_stdio(false);

    vector<int>v(10);

    int n=0;

    generate(v.begin(), v.end(), [&n] { return n++;});

    for(auto item : v)
    {
      cout<<item<<" ";
    }
    cout<<endl;

    return 0;
}

If you really want to use std::fill and are confined to C++98 you can use something like the following,

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

struct increasing {
    increasing(int start) : x(start) {}
    operator int () const { return x++; }
    mutable int x;
};

int main(int argc, char* argv[])
{
    using namespace std;

    vector<int> v(10);
    fill(v.begin(), v.end(), increasing(0));
    copy(v.begin(), v.end(), ostream_iterator<int>(cout, " "));
    cout << endl;
    return 0;
}

There is another option - without using iota. For_each + lambda expression can be used:

vector<int> ivec(10); // the vector of size 10
int i = 0;            // incrementor
for_each(ivec.begin(), ivec.end(), [&](int& item) { ++i; item += i;});

Two important things why it's working:

  1. Lambda captures outer scope [&] which means that i will be available inside expression
  2. item passed as a reference, therefore, it is mutable inside the vector

std::iota is limited to a sequence n, n+1, n+2, ...

But what if you want to fill an array with a generic sequence f(0), f(1), f(2), etc.? Often, we can avoid a state tracking generator. For example,

int a[7];
auto f = [](int x) { return x*x; };
transform(a, a+7, a, [a, f](int &x) {return f(&x - a);});

will produce the sequence of squares

0 1 4 9 16 25 36

However, this trick will not work with other containers.

If you're stuck with C++98, you can do horrible things like:

int f(int &x) { int y = (int) (long) &x / sizeof(int); return y*y; }

and then

int a[7];
transform((int *) 0, ((int *) 0) + 7, a, f);

But I would not recommend it. :)