2012-02-22 8 views
3

ランダム・アクセス・イテレータを使用すると、iter + = nを実行し、!= container.end()の代わりに< container.endループ終了条件として:非ランダム・イテレータ・ストライド非ランダム・アクセス・イテレータ

#include <iostream> 
#include <vector> 

int main(int argc, char *argv[]) 
{ 
    typedef std::vector<float> VectorType; 
    typedef VectorType::const_iterator IteratorType; 

    VectorType v; 
    for(unsigned int i = 0; i < 11; ++i) 
    { 
    v.push_back(i); 
    } 

    for(IteratorType iter = v.begin(); iter < v.end(); iter += 2) 
    { 
    std::cout << " " << *iter; 
    } 

    return 0; 
} 

しかし両方+ = 2と< iter.end()はstd ::セットのようなもののために未定義ているように見えます。他のすべての要素(サブサンプリングする)だけを訪問するだけでいいですか?これを行う別の方法がありますか?ランダムアクセスイテレータで

+0

を試してみてください私は、 iPad上では、コードを試してみることはできませんが、非定数のイテレータを使って試したことがありますか? –

答えて

4

、あなたは、単にiter+=nをやって、その後、実際に条件

を終了ループとして< container.end()代わりの!= container.end()を使用して歩幅を変更することができ、あなたがすることはできません。コードはコンパイルされるかもしれませんが、イテレータが実際にコンテナの最後を過ぎて進んだ場合、実行時に未定義の動作を示します。イテレーターは、そのイテレーターが指し示す範囲の終わりを超えてイテレーターをインクリメントすることはできません。

いずれにせよ、あなたは助けるために関数テンプレートを作成することができますが:

template <typename TForwardIt, typename TDifference> 
bool try_advance(TForwardIt& it, 
       TForwardIt const end, 
       TDifference n) 
{ 
    TDifference i(0); 
    while (i < n && it != end) 
    { 
     ++i; 
     ++it; 
    } 

    return i == n; 
} 
+0

この呼び出しを、ランダムアクセスと他のイテレーターを使用する2つの関数のいずれかにすると、ベクトルなどの場合にはより良いでしょう。 –

+0

@James McNellis: クール、ありがとう。私はこれを次のように使いました:IteratorType iter = v.begin(); while(try_advance(iter、v.end()、2)){std :: cout << "" << * iter; } TDifferenceのアイデアは何でしたか?どうしてですか?template bool try_advance(TForwardIt&it、TForwardIt const end、const unsigned int n){unsigned int i = 0; while(i

2

私はiPad上でので、私はこれをテストすることはできませんが、次の

std::advance(iter, 2); 
+1

+1。それは2つのポジションを進めますが、@Jamesが指摘するコンテナの終わりを過ぎて移動するという問題はまだ存在します。 –

+0

ああ、これは間違いなくパート1の解決策です:) –

+0

境界/ポインタチェックと一緒に使用することはできません。 –

関連する問題