2013-08-28 3 views
7

C++ 11은 원거리 적분 시퀀스에 대해 범위 기반 루프가 없습니다.범위 기반 루프 C++ 11

for(auto e : {0..10}) // wouldn't compile!!! 

그래서 시뮬레이션을 결정했습니다.

template< class T , bool enable = std::is_integral<T>::value > 
struct range_impl 
{ 
    struct iterator 
    { 
     constexpr T operator *()const noexcept { return value; } 
     iterator& operator ++()noexcept { ++value; return *this; } 

     friend 
     constexpr bool operator != (const iterator & lhs, const iterator rhs) noexcept 
     { 
      return lhs.value != rhs.value; 
     } 
     T value; 
    }; 

    constexpr iterator begin()const noexcept { return { first }; } 
    constexpr iterator end ()const noexcept { return { last }; } 

    T first; 
    T last ; 
}; 




template< class T > 
range_impl<T> range(T first , T last) noexcept 
{ 
    return {first, last}; 
} 

int main(){ 
    // print numbers in [ 0..10), i.e. 0 1 2 3 4 5 6 7 8 9 
    for(auto e : range(0,10)) std::cout << e << ' '; 
    std::cout << std::endl; 
} 

Q : ForwardIterators에 대해이 방법을 일반화하는 방법은 무엇입니까?

예 :

template< class ForwardIterator, class T > 
bool find(ForwardIterator first, ForwardIterator last, T const& value) 
{ 
    for(auto e: range(first, last)) if (e == v) return true; 
    return false; 
} 
+3

그건 아니에요 정말 * 일반화 * 그것; 정수는 반복자가 아닙니다. 기본적으로 동일한 이름의 새 기능을 만들고 있습니다. –

답변

6

전문

template< class Iterator> 
struct range_impl<Iterator, false> 
{ 
    range_impl(Iterator first, Iterator last) 
    : first(first), last(last) 
    {} 

    constexpr Iterator begin()const noexcept { return { first }; } 
    constexpr Iterator end ()const noexcept { return { last }; } 

    Iterator first; 
    Iterator last ; 
}; 

테스트 : 당신은 boost::iterator_rangeboost::counting_iterator 다시 구현하려는

int main(){ 
    for(auto e : range(0,10)) std::cout << e << ' '; 
    std::cout << std::endl; 
    const char* a[] = { "Say", "hello", "to", "the", "world" }; 
    for(auto e : range(a, a + 5)) std::cout << e << ' '; 
    std::cout << std::endl; 
} 
+0

정수 기반 범위 구현을 제거 할 수도 있습니다. 대신, 정수 반복자를 생성하고 iterator 기반 범위 구현에 전달하십시오 (코드 중복 감소!). 이것을 개인적으로 구현하는 또 다른 방법은 반복자가 랜덤 액세스이고 정수 반복자가 랜덤 액세스 인 경우 조건부로'size'와'[] '를 정의하는 것입니다. – Yakk

1

. 간단하게이 대신 수행이

template< class T > 
boost::iterator_range< boost::counting_iterator<T> > range(T const& tBegin, T const& tEnd) { 
    return boost::iterator_range< boost::counting_iterator<T> >(tBegin, tEnd); 
} 

도 이미 boost::counting_range 존재합니다 http://www.boost.org/doc/libs/1_47_0/libs/range/doc/html/range/reference/ranges/counting_range.html

+0

for (auto e : temporaryObject {}); -이 경우에는 standart, 즉 temporaryObject 수명이 루프 이후에 끝났음을 보장한다는 것이 무엇입니까? –

+0

나는이 단락을 꺼냈다. 나는 부분적으로 착각했다. 여기를 참조하십시오 : http://stackoverflow.com/questions/9657708/c11-the-range-for-statement-range-init-lifetime – Sebastian

+0

@KhurshidNormuradov 예, 죽습니다. ranged for 루프의 의미는 명확하며 (Google 샘플 구현도 가능함), 그 동안 생성 된 임시 객체의 수명도 포함됩니다 (참조의 임시 수명은 참조 수명입니다). – Yakk

관련 문제