2016-11-01 5 views
0

파이썬 에서처럼 C++에서 사이클을 수행하는 가장 쉬운 방법은 무엇입니까?Cycles in 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); 
} 

또는이 과정에

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

, 그것은이다 이 예제를 사용하기가 어렵지 않거나 단지 for(;;)하지만 간단하고 간결하게 파이썬에서 할 수있는 방법이 있기를 바랍니다.

+2

C++에는 속기가 없다고 생각합니다. 전통적인'for (i = 0; i <10; i ++)를 사용하십시오. – Barmar

+0

_ @ NikBond_ 복제본의 솔루션이 충분히 간단하기를 바랍니다. 단지 10 초 구글 쿼리 였어. –

+0

@Barmar 매일 새로운 것을 배웁니다.) –

답변

1

파이썬 같은 range 개념은 다음과 같이 아웃 오브 더 박스 제공되지 않습니다,하지만 당신은 간단한 반복자와 함께 자신의 Range 클래스를 롤 수 :

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

유명한 관광 명소, 지원하기 위해 for, 반복자 유형 및 begin()/end() 함수가 작업을 수행합니다. (물론 위의 구현은 빠르고 빠르며 향상 될 수 있습니다.)

그런 식으로 자신 만의 클래스를 만들지는 않겠지 만 일단 사용하면 파이썬 접근 방식과 매우 유사합니다 :

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

예 출력 (see live version here) : 당신은 단지 정수 범위를해야하는 경우

$ 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 

, 당신은 또한 (알림에 대한 Yakk, 감사) boost::irange를 사용할 수 있습니다.

+0

부동 소수점은'> = '로 문장을 사용하지 않는 한 나쁜 생각입니다. 오, 당신이 반복기에 m_stop을 저장하자! – Yakk

+0

'm_step'을 개별적으로 템플릿 화하여 무 상태 증가 사례를 허용함으로써 효율성을 높일 수 있습니다. 나는'm_stop'에 대해 신경 쓰지 않는다; 나는 수레와 계단을 위해 그 사용법을 얻었지만 ... – Yakk

+0

'boost; : irange'라고 언급하면이 대답이 향상 될 것입니다. – Yakk