I want to use a special method to initialize a std::vector<unsigned int>
which is described in a C++ book I use as a reference (the German book 'Der C++ Programmer' by Ulrich Breymann, in case that matters). In that book is a section on sequence types of the STL, referring in particular to list
, vector
and deque
. In this section he writes that there are two special constructors of such sequence types, namely, if X
refers to such a type,
X(n, t) // creates a sequence with n copies of t
X(i, j) // creates a sequence from the elements of the interval [i, j)
I want to use the second one for an interval of unsigned int
, that is
std::vector<unsigned int> l(1U, 10U);
to get a list initialized with {1,2,...,9}
. What I get, however, is a vector with one unsigned int
with value 10 :-| Does the second variant exist, and if yes, how do I force that it is called?
there are at least three ways that you can do that. One was mentioned earlier by Brian
//method 1
generate(v.begin(), v.end(), [] { static int i {1}; return i++; });
You can also use std::iota if you are using c++11
//method 2
iota(v.begin(), v.end(), 1);
Or instead you can initialize your container with 1s and then do a partial sum on that. I don't think anybody will use this third method anyway :)
//method 3
vector<int> v(n, 1);
partial_sum(v.begin(), v.end(), v.begin());
A non-boost way to do this with a self-incrementing iterator.
#include <vector>
#include <iostream>
#include <algorithm>
static int NUM_ITEMS = 10;
class gen_range {
public:
gen_range(int i) { idx = i; }
int operator()() { return (idx++); };
int idx;
};
int main() {
std::vector<int> x(NUM_ITEMS);
std::generate_n(x.begin(), NUM_ITEMS, gen_range(0));
for (int i=0; i < x.size(); i++) {
std::cout << x[i] << std::endl;
}
}
C++11:
std::vector<int> idxs (n);
std::generate_n (idxs.begin (), n, [] { static int i {1}; return i++; });
Reread the paragraphs near there describing what each of the parameters are. Specifically, it should mention that i
and j
are not values, but iterators. This constructor is very commonly used to make copies of other types of containers. If you want to get a sequence of values, the Boost library provides a counting iterator, that does exactly what you want.
std::vector<unsigned int> numbers(
boost::counting_iterator<unsigned int>(0U),
boost::counting_iterator<unsigned int>(10U));
No, that variant does not exist. The second constructor initializes a vector from two iterators that point into another sequence.
Here is an example of the "two-iterator" constructor in action:
int fill_data[4] = { 1, 2, 3, 4 };
std::vector<int> v(fill_data, fill_data + 4);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With