c+中的循环+;类似于python(基于范围的)

c+中的循环+;类似于python(基于范围的),python,c++,c++11,range,cycle,Python,C++,C++11,Range,Cycle,在c++中,像在python中一样,最简单的循环方法是什么 for i in range(10): #or range(4, 10, 2) etc foo(i) 我的意思是简单的一句话 for(auto i: range(10)) //or range(4, 10, 2) or range(0.5, 1.0, 0.1) etc foo(i); 但不是这样: std::vector<int> v(10); std::iota(begin(v), end(v), 0)

在c++中,像在python中一样,最简单的循环方法是什么

for i in range(10): #or range(4, 10, 2) etc
    foo(i)
我的意思是简单的一句话

for(auto i: range(10)) //or range(4, 10, 2) or range(0.5, 1.0, 0.1) etc
    foo(i);
但不是这样:

std::vector<int> v(10);
std::iota(begin(v), end(v), 0);
for(auto i: v) {
    foo(i);
}
#include <iostream>

template <typename T>
class Range
{
public:
  class iterator
  {
  public:
    explicit iterator(T val, T stop, T step) : m_val(val), m_stop(stop), m_step(step) { }
    iterator& operator ++ ()
    {
      m_val += m_step;
      if ((m_step > 0 && m_val >= m_stop) ||
          (m_step < 0 && m_val <= m_stop))
      {
        m_val = m_stop;
      }
      return *this;
    }
    iterator operator ++ (int) { iterator retval = *this; ++(*this); return retval; }
    bool operator == (iterator other) const {return m_val == other.m_val;}
    bool operator != (iterator other) const {return !(*this == other);}
    T operator * () const { return m_val; }
  private:
    T m_val, m_stop, m_step;
  };

  explicit Range(T stop)
    : m_start(0), m_stop(stop), m_step(1)
  { }

  explicit Range(T start, T stop, T step = 1)
    : m_start(start), m_stop(stop), m_step(step)
  { }

  iterator begin() const { return iterator(m_start, m_stop, m_step); }
  iterator end() const { return iterator(m_stop, m_stop, m_step); }

private:
  T m_start, m_stop, m_step;
};

template <typename T>
Range<T> range(T stop) { return Range<T>(stop); }

template <typename T>
Range<T> range(T start, T stop, T step = 1) { return Range<T>(start, stop, step); }

int main()
{
  for (auto i : range(10)) { std::cout << " " << i; }
  std::cout << std::endl;
  for (auto i : range(4, 10, 2)) { std::cout << " " << i; }
  std::cout << std::endl;
  for (auto i : range(0.5, 1.0, 0.1)) { std::cout << " " << i; }
  std::cout << std::endl;
}
std::vectorv(10);
标准::物联网(开始(v)、结束(v)、0);
用于(自动i:v){
富(i),;
}
还是这个

for(auto i: []{vector<size_t> v(10); return iota(begin(v), end(v), 0), v;}() ) {
    foo(i);         
}
for(自动i:[{vectorv(10);返回iota(开始(v)、结束(v)、0)、v;}()){
富(i),;
}

当然,使用这些示例或只为(;;)使用
并不困难,但我希望有一种方法可以在python中简明扼要地使用这些示例。

range
这样的python概念不是现成的,但是您可以使用一个简单的迭代器来运行自己的
range
类,如下所示:

std::vector<int> v(10);
std::iota(begin(v), end(v), 0);
for(auto i: v) {
    foo(i);
}
#include <iostream>

template <typename T>
class Range
{
public:
  class iterator
  {
  public:
    explicit iterator(T val, T stop, T step) : m_val(val), m_stop(stop), m_step(step) { }
    iterator& operator ++ ()
    {
      m_val += m_step;
      if ((m_step > 0 && m_val >= m_stop) ||
          (m_step < 0 && m_val <= m_stop))
      {
        m_val = m_stop;
      }
      return *this;
    }
    iterator operator ++ (int) { iterator retval = *this; ++(*this); return retval; }
    bool operator == (iterator other) const {return m_val == other.m_val;}
    bool operator != (iterator other) const {return !(*this == other);}
    T operator * () const { return m_val; }
  private:
    T m_val, m_stop, m_step;
  };

  explicit Range(T stop)
    : m_start(0), m_stop(stop), m_step(1)
  { }

  explicit Range(T start, T stop, T step = 1)
    : m_start(start), m_stop(stop), m_step(step)
  { }

  iterator begin() const { return iterator(m_start, m_stop, m_step); }
  iterator end() const { return iterator(m_stop, m_stop, m_step); }

private:
  T m_start, m_stop, m_step;
};

template <typename T>
Range<T> range(T stop) { return Range<T>(stop); }

template <typename T>
Range<T> range(T start, T stop, T step = 1) { return Range<T>(start, stop, step); }

int main()
{
  for (auto i : range(10)) { std::cout << " " << i; }
  std::cout << std::endl;
  for (auto i : range(4, 10, 2)) { std::cout << " " << i; }
  std::cout << std::endl;
  for (auto i : range(0.5, 1.0, 0.1)) { std::cout << " " << i; }
  std::cout << std::endl;
}
示例输出():


如果你只需要整数范围,你也可以使用(感谢Yakk提醒)。我不认为C++中有任何速记。只需对(i=0;i<10;i++)

@NikBond使用传统的
,我希望复制的解决方案对您来说足够简单。只是10秒的谷歌查询。@Barmar你每天都能学到新东西;)@πάνταῥεῖ: 这个答案似乎不适用于这项任务;它要求您显式写出
{0,1,2,3,4,5,6,7,8,9}
来循环它。快速搜索建议,在的第二个答案中也提到了。浮点型是个坏主意,除非您使用带
=
的sentinal。哦,等等,你在迭代器中存储了m_stop!通过分别模板化
m_步骤
,允许无状态增量1例,可以提高效率。我对停车持怀疑态度;我知道它用于浮点数和步数,但是…提到
boost;:irange
会改进这个答案。@Yakk我同意浮点数至少是危险的——这个例子实际上表明:1.0只是因为浮点数舍入问题才打印出来的。不过,我有意加入浮点,因为Python提供浮点范围。感谢
irange
提示,我编辑了答案。我同意在整数步长-1范围的特殊情况下可以避免
m_-stop
(和
m_-step
),但我将把此类优化的模板专门化留给读者作为练习。;-)