2

remove_ifon の使用中にラムダ式に小さな問題がありますstd::vector

次のコードがあります。

    std::remove_if( openList.begin(), openList.end(), 
        [&](BoardNode& i){
            std::cout<< i.getCoordinates() << std::endl;
            std::cout<< currentNode.getCoordinates() << std::endl;
            return i.getCoordinates() == currentNode.getCoordinates(); }
        );

これにはコンパイラ エラーはありませんが、上記のステートメントから true を返す要素はベクトルから削除されません。

私は画面に印刷されます。

[5,5]
[5,5]

が、元のopenListまま。

4

3 に答える 3

10

std::remove_ifベクトルにアクセスできないため、ベクトルから何も消去しません。代わりに、保持する要素を範囲の先頭に移動し、残りの要素を有効だが未指定の状態のままにして、新しい末尾を返します。

「erase-remove」イディオムを使用して、実際にベクターからそれらを消去できます。

openList.erase(
    std::remove_if( 
        openList.begin(), 
        openList.end(), 
        [&](BoardNode& i){return i.getCoordinates() == currentNode.getCoordinates();}),
    openList.end());
于 2012-11-23T16:49:02.563 に答える
3

ベクターからアイテムを削除するつもりだと思います。しかし、あなたがしていることは、ベクトルからアイテムを実際に削除しない ため、ラムダが機能しないと思われます。と組み合わせてメンバー関数を使用する必要があります。erase()std::remove

つまり、次のように使用する必要がありますerase-remove idiom

v.erase(std::remove_if(v.begin(), v.end(), your-lambda-goes-here), v.end());
于 2012-11-23T16:48:24.657 に答える
0

削除は、消去する要素が上書きされるように、範囲内の要素をシフトすることによって行われます。範囲の古い端と新しい端の間の要素の値は指定されていません。範囲の新しい末尾への反復子が返されます。残っている要素の相対的な順序は保持されます。

http://en.cppreference.com/w/cpp/algorithm/remove

また、そのリンクの例を確認してください。

于 2012-11-23T16:49:29.213 に答える