2013-08-28 13 views
7

C++ 11は、レンジ積分シーケンスのレンジベースループがありません。範囲ベースのループC++ 11(L、R)

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

テスト

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

整数ベースの範囲の実装を削除することもできます。代わりに整数のイテレータを作成し、イテレータベースの範囲実装に渡します(コードの重複を減らします)。私の個人的な実装では、イテレータがランダムアクセスで、整数イテレータがランダムアクセスの場合、条件付きで 'size'と' [] 'が定義されています。 – Yakk

1

あなたはboost::iterator_rangeboost::counting_iteratorを再実装しようとしています。単純に、この代わりに行います。そこ

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_rangehttp://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

関連する問題