2017-08-02 2 views
0

std::vectorC++と一緒に使用して、一部のアイテムを保存します。&後で取得します。以下は私のベクトルをどのように反復しているかです。繰り返すサイクルでstd :: vectorをループする方法

std::vector<some_object> some_vector; 
some_vector.resize(10); 

for (auto it = some_vector.begin(); it != some_vector.end(); ++it) { 
    int current_it_index = std::distance(some_vector.begin(), it); 
} 

私は繰り返しごとにインデックスが必要です。したがって、上記のように繰り返しごとにそれを取得します。

上記のループは正常に動作します。ですが、は、無限サイクルでベクターをループしたいと考えます。。どうやってやるの?

ここで、実行中のループを繰り返しサイクルで実行させると、どのように停止するのでしょうか?私は&がかなりうまくいくはずだという信号を送る変数としてstd::atomic<bool>を使うことを考えていますか?

PS:質問を説明するコンテナの例としてstd::vectorを使用しました。提案された解決策がstd::arrayまたは他のコンテナでも機能することができれば素晴らしいでしょう。

+3

簡単なwhileループがこのトリックを行います。それを考えるのではなく、現在の 'for'ループを' std :: atomic 'をチェックする' while'ループにラップしてください。しかし、あなたがすでに持っている 'for'ループだけを使って行うことができます。あなたは2つのことを変更する必要があります:1)最後にイテレータをリセットし、2)あなたが知るために述べた' std :: atomic 'いつ止めるか。 – DimChtz

+1

'current_it_index'がベクトルをもう一度やり直すか、それとも増加し続けるべきかの後に' current_it_index'を '0'にリセットしますか?また、XY問題のような音がします。なぜあなたがこれをやっているのかを教えてくれたら、あなたに別のものを指摘することができます。 – NathanOliver

+0

'for(auto it = some_vector.begin();; ++ it){ int current_it_index = std :: distance(some_vector.begin()、it); if(it == some_vector.end()-1)it = some_vector.begin(); } ' –

答えて

3
std::vector<some_object> some_vector; 
some_vector.resize(10); 
bool quit = false; 
while (!quit) { 
    for (auto& e:some_vector) { 
    if (quit) break; 
    std::size_t i = std::addressof(e)-some_vector.data(); 
    // ... 
    } 
} 
1

2の累乗を持つ配列を反復処理する一般的な方法は、単純にカウンタを反復してマスク操作を使用することです。

size_t counter = 0; 
const size_t mask = some_vector.size() - 1U; 

while (!quit) { 
    size_t i = counter++ & mask; 
    do_something(some_vector[i]); 
} 

アレイのパワーが2でない場合は、フリーランニングカウンタをマスキングする代わりにモジュロ演算を実行できます。あなたは非ランダム・アクセス・コンテナを使用して、イテレータとインデックスを必要としている場合は

size_t i = 0; 
const size_t n = some_vector.size(); 

while (!quit) { 
    do_something(some_vector[i++]); 
    i %= n; 
} 

、その後、次の2つのループを実装することができます。これは非ランダムアクセスイテレータ上で計算することの費用を避けるでしょう。

for (;;) { 
    size_t idx = 0; 
    for (auto it = some_container.begin(); 
     it != some_container.end(); 
     ++it) { 
     do_something(it, idx++); 
    } 
+0

これは、イテレータの代わりにインデックスを取得します。これは 'vector'では動作しますが、' list'やその他の非連続データ構造では機能しません。 –

+0

'deque'のために動作しますが、これは連続していません。 – jxh

+0

十分に公正。私のコメントは不正確でした。本質的に間違っていたわけではありません。これは 'operator []'、 'at()'、 'size_t 'を要素に変換する他の方法なしでは動作しません。 –

1

私が正しく理解していれば、コンテナの最後の要素に到達すると、コンテナの先頭にジャンプするだけです。

auto first = std::begin(c); 
const auto last = std::end(c); 
std::size_t idx = 0; 

while (!should_exit()) { 
    do_something(idx); 

    ++idx; 
    if (++first == last) { // reset 
     idx = 0; 
     first = std::begin(c); 
    } 
} 

これはどのSTLスタイルのコンテナに対しても有効です。イテレータとインデックスの両方を持つことはおそらく必要ありませんが、std::listやベクトル/配列のような非ランダムアクセスコンテナでも機能するKISSソリューションです。

+0

一般に、このコードは、do_something()がイテレータを無効にしたり、コンテナを変更したりすることはないという危険性があります。 –

関連する問題