2016-07-17 4 views
1

私は、フォームのループのための簡単なを交換したいと思います:フォームのイテレータとベクトルを使用せずにfor(auto i:<something>)を(auto i = 0; i <n; i ++)...に置き換えることはできますか?

for (auto i=0;i<n;i++) { 
    whatever; 
} 

for (auto i: <something>) ... 

私はそれがベクトルで行うことができます知っているが、私はドン」ベクトル を宣言する必要があります。

for (auto i: 1..n) ... 

はこれが可能である。理論的には

は、私のようなような単純なものをご希望ですか?

ありがとうございました。

+1

可能ですか?はい、もちろん。内蔵ですか?未だに。 – ildjarn

+0

これはむしろMatlabやJavaの 'for'ループのように見えますが、C++では見えません。 – Polb

+3

私は*問題が解決されていることを知りたいと思っています*それは前者ではなく後者をやりやすくします。 [Range-for](http://en.cppreference.com/w/cpp/language/range-for)は、次のようなものです: 'begin()'で範囲を公開しているオブジェクトに対するforループ構造、および'end()'構造体です。あなたが簡単な数値シーケンスでそれをしたいのであれば、それを行うオブジェクトを書くのは難しくありません。しかし、再び、*なぜ迷惑? – WhozCraig

答えて

7

組み込みソリューションはありません。

あなたがしたい場合は、このようBoost.counting_rangeを使用することができます。

#include <iostream> 
#include <boost/range/counting_range.hpp> 

int main() { 
    for (auto v : boost::counting_range(2,13)) 
     std::cout << v << "\n"; 
} 

(live)または独自のロール。ブースト範囲はすべての数値を保存するわけではありませんが、イテレータのペアをラップします。 (概念的にPython2 xrangeやPython3 と概念的に似ています)

これは、単に手作業でループを書くよりも簡単で良いかどうかは、読者が決定することです。


補遺:あなたがあなた自身のソリューションを展開したい場合は、間接参照に番号を返すいくつかのイテレータを書き、増分上の内部数が増加し、内部番号が等しい場合に等しいと比較されます。次に、そのようなイテレータを返すための関数beginendを提供するラッパークラスを記述します。

Boost.counting_iteratorは、反復子の実装であり、そして上記のようにBoost.counting_range範囲としてそれを包みます。

1

これには組み込みのソリューションはありません。それで全部です。


それは次のようにあなたがあなた自身のために似た何かを定義することができます。

#include<functional> 
#include<cstddef> 
#include<array> 
#include<iostream> 

template<std::size_t... I> 
constexpr auto seq(std::integer_sequence<std::size_t, I...>) { 
    return std::array<std::size_t, sizeof...(I)>{ I... }; 
} 

template<std::size_t N> 
constexpr auto seq() { 
    return seq(std::make_index_sequence<N>()); 
} 

int main() { 
    for(auto i: seq<10>()) { 
     std::cout << i << std::endl; 
    } 
} 

あなたがNに0以外の範囲に対処したい場合は、代わりにこれを行うことができます:

#include<functional> 
#include<cstddef> 
#include<array> 
#include<iostream> 

template<std::size_t N, std::size_t... I> 
constexpr auto seq(std::integer_sequence<std::size_t, I...>) { 
    return std::array<std::size_t, sizeof...(I)>{ (N+I)... }; 
} 

template<std::size_t N, std::size_t M, std::enable_if_t<(N<M)>* = nullptr> 
constexpr auto seq() { 
    return seq<N>(std::make_index_sequence<M-N>()); 
} 

int main() { 
    for(auto i: seq<3, 7>()) { 
     std::cout << i << std::endl; 
    } 
} 

このソリューションにはC++ 14リビジョンが必要です。


データ構造をインスタンス化する必要はありません別の解決策は、次のいずれかです。

#include<functional> 
#include<cstddef> 
#include<array> 
#include<iostream> 
#include<utility> 

template<std::size_t N, typename F, std::size_t... I> 
constexpr void seq(F &&f, std::integer_sequence<std::size_t, I...>) { 
    int arr[] = { (std::forward<F>(f)(I+N), 0)... }; 
} 

template<std::size_t N, std::size_t M, typename F, std::enable_if_t<(N<M)>* = nullptr> 
constexpr void seq(F &&f) { 
    seq<N>(std::forward<F>(f), std::make_index_sequence<M-N>()); 
} 

int main() { 
    seq<3, 7>([](int i){ 
     std::cout << i << std::endl; 
    }); 
} 

そうarrは、コンパイラによって一掃されますが、それはのためのように少ないビットを探しますループ。

+0

あなたのソリューションに感謝します。しかし、この解決策では、範囲(ベクトルではなく配列)に等しいサイズのデータ​​構造も必要です。私はこれの主な欠点は、ループ内の反復回数を多くの要素に割り当てる必要があることだと思います。 – dmg

+0

@dmg質問が更新されました。別の方法は、 'begin'と' end'が存在するカスタムの反復可能なデータ構造を定義し、それを使用することです。とにかく、ここにはたくさんの提案があります。興味深いものを見つけたらあなたの好きなものを選んでください。それ以外の人は将来の読者のためにそこにいます。 – skypjack

7
template<class T> 
struct index_it{ 
    T t; 
    void operator++(){++t;} 
    T operator*()const{ return t; } 
    friend bool operator==(index_it const& lhs,index_it const& rhs){ 
    return lhs.t==rhs.t; 
    } 
    friend bool operator!=(index_it const& lhs,index_it const& rhs){ 
    return lhs.t!=rhs.t; 
    } 
}; 
template<class T> 
index_it<T> index(T t){return {t}; } 

これは非常に最小限のインデックス「イテレータ」です。実際にはイテレータではないため、公理に違反していますが、for(:)ループでは十分であることが保証されています。

for(:)ループの対象となる最小限の範囲です。

インデックスの範囲を指定します。

使用:

for(auto i:indexes<int>(0,n)) 

楽しみのために、これはまた、私たちを与える:あなたはちょうどそのように、コンテナまたは範囲の有効なイテレータを反復することができます

template<class R> 
auto iterators(R& r){ 
    using std::begin; using std::end; 
    return indexes(begin(r), end(r)); 
} 

を。あなたが実際に何かを試してみると、問題は同じものですindex_it

for(auto it:iterators(vec)) 

live example

関連する問題