在C++/STL中是否有一个与Python range()相当的紧凑型

M-V*_*M-V 53 c++ python

如何使用C++/STL执行以下等效操作?我想填充std::vector一系列值[min,max].

# Python
>>> x = range(0, 10)
>>> x
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Run Code Online (Sandbox Code Playgroud)

我想我可以使用std::generate_n并提供一个函子来生成序列,但我想知道是否有更简洁的方法使用STL这样做?

chr*_*ris 61

在C++ 11中,有std::iota:

std::vector<int> x(10);
std::iota(std::begin(x), std::end(x), 0); //0 is the starting number
Run Code Online (Sandbox Code Playgroud)

  • 它不太一样.iota填充现有容器,而范围本身是可迭代的,但实际上并没有_contain_值.可以在几十亿个项目上制作Python范围而不会出现问题,但不要尝试使用iota.你实际上必须创建一个容器,其中包含足够的元素. (12认同)
  • @FelixDombek,看看[这个问题](http://stackoverflow.com/questions/9244879/what-does-iota-of-stdiota-stand-for) (4认同)
  • *iota*代表什么? (3认同)
  • `std :: iota`可以通过包含`#include <numeric>`来使用 (3认同)
  • @André,我同意,Eric Niebler 在这方面做了一些很棒的工作。他的`view::iota` (IIRC) 应该与 Python 非常相似,是无限的和懒惰的。 (2认同)

Man*_*rse 21

boost :: irange:

std::vector<int> x;
boost::push_back(x, boost::irange(0, 10));
Run Code Online (Sandbox Code Playgroud)

  • 啊,Boost的奇迹:)这肯定是正确的C++ 03答案. (3认同)
  • `#include &lt;boost/range/algorithm_ext/push_back.hpp&gt; #include &lt;boost/range/irange.hpp&gt;` (2认同)

Cla*_*diu 8

我最终编写了一些实用函数来做到这一点。您可以按如下方式使用它们:

auto x = range(10); // [0, ..., 9]
auto y = range(2, 20); // [2, ..., 19]
auto z = range(10, 2, -2); // [10, 8, 6, 4]
Run Code Online (Sandbox Code Playgroud)

代码:

#include <vector>
#include <stdexcept>

template <typename IntType>
std::vector<IntType> range(IntType start, IntType stop, IntType step)
{
  if (step == IntType(0))
  {
    throw std::invalid_argument("step for range must be non-zero");
  }

  std::vector<IntType> result;
  IntType i = start;
  while ((step > 0) ? (i < stop) : (i > stop))
  {
    result.push_back(i);
    i += step;
  }

  return result;
}

template <typename IntType>
std::vector<IntType> range(IntType start, IntType stop)
{
  return range(start, stop, IntType(1));
}

template <typename IntType>
std::vector<IntType> range(IntType stop)
{
  return range(IntType(0), stop, IntType(1));
}
Run Code Online (Sandbox Code Playgroud)


小智 6

多年来我一直在使用这个库来实现这个目的:

https://github.com/klmr/cpp11-range

效果很好,并且代理已被优化。

for (auto i : range(1, 5))
    cout << i << "\n";

for (auto u : range(0u))
    if (u == 3u) 
        break;
    else         
        cout << u << "\n";

for (auto c : range('a', 'd'))
    cout << c << "\n";

for (auto i : range(100).step(-3))
    if (i < 90) 
        break;
    else        
        cout << i << "\n";

for (auto i : indices({"foo", "bar"}))
    cout << i << '\n';
Run Code Online (Sandbox Code Playgroud)