C ++中的循环(如python)(基于范围) [英] Cycles in c++ like in python (range-based for)

查看:68
本文介绍了C ++中的循环(如python)(基于范围)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在c ++中像在python中那样在c ++中执行循环的最简单方法是什么?

What is the easiest way to do cycles in c ++ like in python?

for i in range(10): #or range(4, 10, 2) etc
    foo(i)

I意思是简单的单行代码

I mean something simple and one-line like this

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);
}

或者这个

for(auto i: []{vector<size_t> v(10); return iota(begin(v), end(v), 0), v;}() ) {
    foo(i);         
}

当然,使用这些示例并不困难,或者仅使用 for(;;),但我希望有一种方法可以在python中简短地进行。

Of course, it is not difficult to use these examples or just for(;;) but I hope there is a way to do it briefly and succinctly in python.

推荐答案

不提供现成的类似Python的 range 概念,但是您可以滚动自己的 Range 类,具有一个简单的迭代器,例如:

A Python-like range notion is not provided out-of-the-box, but you could roll your own Range class with a simple iterator, like this:

#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;
}

为了支持基于范围的 ,迭代器类型和 begin() / end()函数将完成此工作。 (当然,我上面的实现是快速而肮脏的,并且可能会得到改进。)

In order to support range-based for, an iterator type and begin()/end() functions will do the job. (Of course my implementation above is quick and dirty, and could probably be improved.)

您不会像那样滚动自己的类,但是一旦有了它,其用法与Python方法非常相似:

You will not get around rolling your own class like that, but once you have it, the usage is very much akin to the Python approach:

for (auto i : range(stop)) { ... }
for (auto i : range(start, stop, step)) { ... }

示例输出(在此处查看实时版本):

$ g++ -std=c++11 -o test test.cpp && ./test
 0 1 2 3 4 5 6 7 8 9
 4 6 8
 0.5 0.6 0.7 0.8 0.9 1

如果只需要整数范围,还可以使用 boost :: irange (感谢Yakk的提醒)。

If you only need integer ranges, you can also use boost::irange (thanks to Yakk for the reminder).

这篇关于C ++中的循环(如python)(基于范围)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆