0

私はこのコードを持っています:

#include <algorithm>
#include <iostream>
#include <list>

using namespace std;

struct P
{
    bool operator()(const int &n) const
    {
        return n % 3 == 0;
    }
};

int main()
{
    std::list<int> l({ 5, 2, 6, 1, 13, 9, 19 });
    std::cout << l.size();
    std::remove_if(l.begin(), l.end(), P());
    std::cout << l.size() << std::endl;

    return 0;
}

「77」を出力します。P 構造体の演算子 () は、その引数に 3 による除算の余りがない場合に true を返すため、「75」が出力されると予想していました。 7つのうち)。何か不足していますか?

ありがとう。

4

3 に答える 3

1

remove/シーケンスを並べ替えるremove_ifだけで、変更はしません。イテレーターは、元のコンテナーにアクセスしたり、コンテナーを認識したりしません。結果を適切なコンテナー メンバーに渡す必要があります。erase

l.erase(std::remove_if(l.begin(), l.end(), P()), l.end());

2 番目を忘れないでください。これにより、範囲全体が消去されるl.end()2 つの反復子のオーバーロードが得られます。eraseそれを忘れると、1 つの要素だけを消去する 1 つの反復子のオーバーロードになってしまいます。

于 2014-03-09T22:19:07.857 に答える
1

http://www.cplusplus.com/reference/algorithm/remove_if/から引用するには

この関数は、要素の範囲を含むオブジェクトのプロパティを変更できません (つまり、配列またはコンテナーのサイズを変更できません): pred が true を返す要素を、pred が true を返す次の要素に置き換えることによって、削除が行われます。そうではなく、新しい末尾要素と見なされる要素に反復子を返すことによって、短縮された範囲の新しいサイズを通知します。

つまり、指定された範囲内の要素を再配置して、削除されていない要素がすべて先頭にくるようにし、削除されていない部分の末尾のすぐ後ろにイテレータを返します。ただし、基になるコンテナーについて何も知らないため、要素を削除することはできません。

于 2014-03-09T22:11:37.107 に答える