web-dev-qa-db-ja.com

vector :: endをvectorから消去する

私が使用するとき、それは正しく動作しますか(何もしません)

_ vector<T> v;
 v.erase(v.end());
_

のようなものを使いたい

_ v.erase(std::find(...));
_

ifである必要がありますかv.end()ですか?
C++。com および CPPreference に関する情報はありません

35
RiaD

標準では詳しくは説明されていませんが、v.erase(q)が定義されており、_[sequence.reqmts]_の「qが指す要素を消去します」。これは、qが実際に要素を指している必要があることを意味します。これは、終了反復子では指しません。終了反復子を渡すことは未定義の動作です。

残念ながら、あなたは書く必要があります:

_auto it = std::find(...);
if (it != <the part of ... that specifies the end of the range searched>) {
    v.erase(it);
}
_

もちろん、次のように定義できます。

_template typename<Sequence, Iterator>
Iterator my_erase(Sequence &s, Iterator it) {
    if (it == s.end()) return it;
    return s.erase(it);
}

my_erase(v, std::find(v.begin(), v.end(), whatever));
_

結合コンテナのc.erase()voidを返すため、このテンプレートをすべてのコンテナに一般化するには、いくつかの_-> decltype_アクションが必要です。

29
Steve Jessop

end()を消去する(あるいは、end()のターゲットを確認する)ことは、未定義の動作です。未定義の動作は、プラットフォームでの「ただ動作する」など、あらゆる動作を許可されます。それはあなたがそれをしなければならないという意味ではありません。それはまだ未定義の振る舞いであり、私はあなたが後でそれを最も期待しないときに最悪の方法であなたに噛み付くでしょう。

ここでは、setではなく、vectorまたはunordered_setを検討することをお勧めします。

24
Billy ONeal

これを試しましたか?

v.erase(remove_if(v.begin(), v.end(), (<your criteria>)), v.end());
6
Gaffi