5

std::vectors およびより一般的にはすべての STL コンテナーについて、次のコードが正しくないことはわかっています。

std::vector<something>::iterator it = array.begin();
for(; it != array.end(); it++) {
   ...
   array.erase(it);
   ...
}

イテレータは消去と要素の後に更新する必要があるためです。

ブーストマルチインデックスでも同じかどうか疑問に思っていました。たとえば、次のようなものが正しいかどうか:

my_index::iterator it = index.get<0>().begin();
for(; it != index.get<0>().end(); it++) {
   ...
   index.erase(it);
   ...
}

ドキュメントの次の段落をよく理解したいと思います: http : //www.boost.org/doc/libs/1_51_0/libs/multi_index/doc/tutorial/indices.html#guaranteesイテレータを無効にすることなく消去できます。ただし、要素を削除したため、反復中にアクセスすることになっている別の要素が現在の反復子の位置の前に移動され、アクセスされない可能性があるかどうかはわかりません (つまり、反復中にいくつかの要素を消去することにより、私はまだすべての要素を通過することを確信していますか?)。

ありがとう!

4

2 に答える 2

7

リンクした段落は、ハッシュされた (順序付けられていない) インデックスにのみ適用されます。新しい要素を挿入するとき、ハッシュされたインデックス反復子は有効なままであると述べています。

消去する場合、順序付けられたインデックスに対して、次の戻り値を使用することにより、常に完全な反復を保証できますerase

for (; it != index.get<0>().end(); ) {
    if (...) it = index.erase(it);
    else ++it;
}

これは、要素の消去に対して反復順序が安定しているため、ハッシュ化された (順序付けされていない) インデックスでも機能します。

于 2012-10-22T09:10:35.790 に答える
3

いいえ、あなたの行動はブーストインデックスでは無効です。コレクションから消去されたイテレータが有効なままになることはありません。有効なままにできるのは、コレクション内の他のイテレータです。これらをどこかに保存する必要があります。

実際のテキストは次のとおりです。

イテレータの有効性と例外安全性を保証します

Boost.MultiIndexフレームワークによって課せられる内部制約により、ハッシュインデックスは、順序付けされていない連想コンテナーに関して、C ++標準ライブラリテクニカルレポート(TR1)で要求されるよりも実際に強力なイテレーターの有効性と例外安全性を保証します。

挿入または再ハッシュ中は、どのような場合でもイテレータの有効性が保持されます。TR1では、再ハッシュ(暗黙的または明示的)が実行されたときにイテレータを無効にできます。内部ハッシュ関数と等式述語オブジェクトは実際には呼び出されないため、イテレータを介して要素または要素の範囲を消去しても、スローされることはありません。rehashは、無条件に強力な例外安全性の保証を提供します。

TR1は、内部ハッシュ関数と等式述語オブジェクトがスローされない場合にのみそれを保証します。やや意外な結果は、再ハッシュ中に例外がスローされた場合、TR1準拠の順序付けされていない連想コンテナが要素を消去する可能性があることです。一般に、これらのより強力な保証は、ユーザーの利便性、特にイテレーターの安定性に有利に働きます。ただし、(できれば最小限の)パフォーマンスの低下により、これらの商品と交換される可能性があります。

于 2012-10-22T09:06:10.830 に答える