20

私が持っているとしましょうstd::vector<std::pair<int,Direction>>

ベクトルからペアを削除するために、erase-remove_if イディオムを使用しようとしています。

stopPoints.erase(std::remove_if(stopPoints.begin(),
                                stopPoints.end(),
                                [&](const stopPointPair stopPoint)-> bool { return stopPoint.first == 4; }));

.first 値が 4 に設定されているすべてのペアを削除したいと考えています。

私の例では、ペアがあります:

- 4, Up
- 4, Down
- 2, Up
- 6, Up

ただし、erase-remove_if を実行すると、次のものが残ります。

- 2, Up
- 6, Up
- 6, Up

ここで何が間違っていますか?

4

2 に答える 2

13

メソッドstd::vector::eraseには 2 つのオーバーロードがあります。

iterator erase( const_iterator pos );
iterator erase( const_iterator first, const_iterator last );

最初のものは at 要素のみを削除しpos、2 番目のものは range を削除します[first, last)

呼び出しで反復子を忘れたためlast、オーバーロードの解決によって最初のバージョンが選択され、最後にシフトされた最初のペアのみが削除されstd::remove_ifます。これを行う必要があります:

stopPoints.erase(std::remove_if(stopPoints.begin(),
                                stopPoints.end(),
                                [&](const stopPointPair stopPoint)-> bool { 
                                    return stopPoint.first == 4; 
                                }), 
                 stopPoints.end());

消去削除イディオムは次のように機能します。ベクトルが{2, 4, 3, 6, 4}あり、次のものを削除するとします4

std::vector<int> vec{2, 4, 3, 6, 4};
auto it = std::remove(vec.begin(), vec.end(), 4);

{2, 3, 6, A, B}「削除された」値を最後に配置することでベクトルをに変換し(値AB最後は未指定です(値が移動されたかのように)、これが例で取得した理由です6)にイテレータを返しますA(最初の「削除された」値の)。

もしあなたがそうするなら:

vec.erase(it)

... の最初のオーバーロードstd::vector::eraseが選択され、と getitであるat の値のみを削除します。A{2, 3, 6, B}

2 番目の引数を追加すると、次のようになります。

vec.erase(it, vec.end())

...2 番目のオーバーロードが選択され、 と の間の値が消去されるため、 とitvec.end()両方が消去されます。AB

于 2016-08-18T13:47:08.400 に答える