9

Say I want all numbers from 23 to 57 be in a vector. I can do this:

vector<int> result;
for (int i = 23; i <= 57; ++i)
{
    result.push_back(i);
}

But this is a 5 line solution for a simple job. Can't I do that more elegantly? The best syntax would be vector<int> result{23 .. 57}; for example or such a trivial one line code. Any options with C++17?

iBug
  • 35,554
  • 7
  • 89
  • 134
Narek
  • 38,779
  • 79
  • 233
  • 389

3 Answers3

17

You can use std::iota (since C++11).

Fills the range [first, last) with sequentially increasing values, starting with value and repetitively evaluating ++value.

The function is named after the integer function ⍳ from the programming language APL.

e.g.

std::vector<int> result(57 - 23 + 1);
std::iota(result.begin(), result.end(), 23);
Community
  • 1
  • 1
songyuanyao
  • 169,198
  • 16
  • 310
  • 405
6

With range-v3, it would be:

const std::vector<int> result = ranges::view::ints(23, 58); // upper bound is exclusive

With C++20, std::ranges::iota_view:

const auto result1 = std::ranges::views::iota(23, 58); // upper bound is exclusive
const auto result2 = std::ranges::iota_view(23, 58); // upper bound is exclusive
Jarod42
  • 203,559
  • 14
  • 181
  • 302
0

Yet another possibility is to use boost::counting_iterator[1]. This also has the advantage of working with C++98, should you be unfortunate enough to be stuck with it.

#include <boost/iterator/counting_iterator.hpp>

result.insert(result.end(), boost::counting_iterator<int>(23), boost::counting_iterator<int>(58));

or, even simpler:

vector<int> result(boost::counting_iterator<int>(23), boost::counting_iterator<int>(58));

Note that, as a normal half-open range is expected in either case, you'll have to use lastNum+1, and you will not be able to insert numeric_limits<int>::max() (aka INT_MAX) for this reason.

[1] https://www.boost.org/doc/libs/1_67_0/libs/iterator/doc/counting_iterator.html

Arne Vogel
  • 6,346
  • 2
  • 18
  • 31