2017-02-18 8 views
1

は、次のコードスニペットを取る:C++のforループの条件を動的に更新する方法は?

// x is a global vector object that holds values of type string as follows, vector<string> x 
// x is filled/populated via the function Populate_x(y,z); 

Populate_x(y,z); 

for (auto i : x) 
{ 
string v = check(i);  
Populate_x(v,v); 
} 

私の質問は、どのように私は動的ためのループ内からPopulate_x(V、V)を呼び出すときに上に示したforループベースの範囲内のxを更新することができますか?これが可能なのかどうかはわかりません。そうでない場合は、この動作を達成するためにコードをどのように再構築できますか?

あなたの提案は大変ありがとうございます。

+0

より完全なサンプルが役立つかもしれませんが、関連する範囲を行う必要はないため、従来のforループやおそらくwhileループなどの他の解決策を使用する必要があります。より完全なサンプルがなければ、特定のサンプルコードを提供することは困難です。 – user34660

答えて

3

d forループは、およそ:1)コンテナの開始と終了イテレータを取得する。2)一時イテレータを使用して、最初のイテレータ値から最後のイテレータ値まで反復する。3)各反復で、一時イテレータを逆参照し、範囲外ループの変数を逆参照されたイテレータ値に置き換えます。

...多かれ少なかれ。一番下の行は、1)範囲ベースのforループが範囲の開始イテレータと終了イテレータを取得して使用し、2)コンテナがベクターであることを示しています。わかっているように、ベクトルを変更すると無効になりますほとんどのイテレータはベクトルの内容になります。

ベクターの内容の特定の種類の変更では、特定のイテレータは無効にならず、有効なままであることは事実です。しかし実際には、std::vector::iteratorまたはstd::vector::const_iteratorをどこかに持っていれば、ベクトルを変更することは、イテレータがもはや有効ではないということを前提とすることは安全です。私が言及したように、必ずしも100%真実ではありませんが、それはかなり安全な前提です。

範囲の反復では、反復のライフタイムの間、コンテナに対するイテレータが取得され、使用されるため、ベクトル上で範囲の反復を行い、反復中にベクトルを変更します。ベクトルに対する任意の変更は、ベクトルに対する継続的な反復に対して、未定義の動作をもたらす可能性が高い。

「変更」は、本質的にベクトルからの値の挿入または削除を意味することに注意してください。すなわち、ベクターそのものの改変。ベクターのの値をに変更しても、既存のイテレーターの有効性には何の影響もなく、安全です。

このプロセス中にベクターを繰り返し処理したい場合(ベクターに値を挿入または削除するという変更を加えて)、ベクターを安全に変更する場合は、まず自分自身で答える必要がありますまたは反復のための削除の平均。それはあなたが自分自身を理解しなければならないものです。たとえば、ループが現在ベクトルの4番目の要素にあり、ベクトルに新しい2番目の値を挿入すると、ベクトルに値を挿入すると、ベクトルの残りの値がすべてシフトされます。 vectorはベクトルの5番目の要素になります。これを正しく実行すると、次の繰り返しでは、ベクトルの5番目の要素は以前繰り返したものと同じになります。これは、あなたの望むことですか?それは、まず自分自身に答える必要があるものです。

しかし、これまでのように安全に反復中のベクトルを修正すること、ほとんどの最も簡単な方法は、完全にイテレータを使用して回避し、インデックス変数を使用することです:今

for (size_t i=0; i<x.size(); ++i) 
{ 
    auto v=x[i]; 

    // ... 
} 

を、ベクトルの修正は、完全に安全であり、すべてのあなたは、どのような場合にの後にのベクトルが変更されたかを把握しなければなりません。iインデックス変数が調整を必要とするかどうかは問われません。

質問にお答えください。

+0

詳細な書き込みのためにサムに感謝します。仰るとおりです。 – Xigma

+0

提案されたソリューションが機能します。私はなぜ今なぜ見ることができます。 – Xigma

1

あなたの説明から、xを動的に更新することが何を意味するのかよく分かりません。

Populate_x xに新しい要素を追加する

Populate_x関数がベクトルxの一部の要素をpush_backにしようとすると、それはできません。詳細ベクトルが変更されたときにループが使用する反復子が無効化されるので、未定義の動作のループ結果内部ベクトルを変更

ためthis answerを参照。

もしそうなら、あなたがxの終わりに複数の要素を追加したい場合は、実用的な方法はyに一時的vector<string> y;push_back/emplace_back要素を使用することであろう、そしてあなたはすべて追加する準備が整いましたら、 xyの要素は、この場合にはthisに似た何かを(行うv1で、v2はあなたのyあなたxです:範囲ベース

x.insert(x.end(), make_move_iterator(y.begin()), make_move_iterator(y.end())); 
+0

ありがとうVincent!それはまさに私が欲しいものです。そして、あなたの仮定は正しいです、私はベクトルxにいくつかの要素をプッシュバックしています。私はあなたの提案された解決策の手順に従ったが、xはPopulate_x関数を介して更新されているにも関わらず、forループではまだ更新を受けていない。 – Xigma

関連する問題