2016-06-16 4 views
2

繰り返される処理を防ぐために、要素の一部を削除しながら、ベクトルの要素を1つのステップで反復することはできますか? (私はフラグメントは偽ですけど、私が欲しいものを示す)ベクターを反復処理してその特定の要素を削除する安全な方法は何ですか

std::vector<MyRecord*>* BLV = GetVector(); 
for (std::vector<MyRecord*>::iterator it = BLV->begin(); it != BLV->end(); ++it) 
{ 
    MyRecord* BL = *it; 
    if(Selected) 
    { 
    delete BL; 
    BLV->erase(it); 
    } 
} 
+0

はhttp://stackoverflow.com/questions/3938838/erasing-from-a-stdvector-while-doing-a-for-each –

+1

の可能性のある重複あなたはunique_ptrを年代のベクトルを使用して適用について考えたことがあります消し去りイディオム? – MikeMB

+1

'MyRecord'と' LinkRegisterRecord'の関係は何ですか? – songyuanyao

答えて

0

songyuanyaoにループを変更するには、すでにあなたに素敵な答えを与えた:一言で言えば、あなたはeraseによって返された値に、あなたのイテレータをリセットする必要があります。

ただし、該当する場合は、unique_ptrとイレーズ・イディオムのベクトルを使用することをお勧めします(これは、要素を1回だけ移動するので効率的です)。

std::vector<std::unique_ptr<MyRecord>>* BLV = GetVector(); 
BLV->erase(
    std::remove_if(BLV->begin(), BLV->end(), 
     [&](const std::unique_ptr<MyRecord>& rec) { return Selected; } 
    ), 
    BLV->end() 
); 
8

std::vector::eraseを消去する要素にイテレータを無効になり、その後、++it;はUBにつながります。

end()イテレータを含め、イレースポイントと参照ポイントを消去ポイント以降で無効にします。

戻り値はerase()です。

最後に削除された要素に続くイテレータ。イテレータposが最後の要素を参照する場合、end()イテレータが返されます。

その後、

for (std::vector<MyRecord*>::iterator it = BLV->begin(); it != BLV->end();) 
{ 
    MyRecord* BL = *it; 
    if(Selected) 
    { 
    delete BL; 
    it = BLV->erase(it); 
    } else 
    { 
    ++it; 
    } 
} 
関連する問題