문제

I've this code:

#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;
}

prints out "77". I expected it would have printed out "75", because the operator () of the P struct, returns true when its argument has not remainder of the division by 3. And that's the case for '6' and '9' (two elements out of seven). Am I missing something ?

thanks.

도움이 되었습니까?

해결책

To quote from http://www.cplusplus.com/reference/algorithm/remove_if/

The function cannot alter the properties of the object containing the range of elements (i.e., it cannot alter the size of an array or a container): The removal is done by replacing the elements for which pred returns true by the next element for which it does not, and signaling the new size of the shortened range by returning an iterator to the element that should be considered its new past-the-end element.

In other words, it rearranges the elements in the given range so that all the non-removed ones are at the beginning, then returns an iterator just past the end of the non-removed part. But it can't delete any elements, because it doesn't know anything about the underlying container.

다른 팁

Is it possible std::remove_if returns the resulting list?

remove/remove_if only reorders a sequence, it doesn't modify it. Iterators have no access to or knowledge of the container from which they come. You need to pass the result to a suitable erase container member:

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

Don't forget the second l.end() so that you get the two-iterator overload of erase that erases a whole range. If you forget it, you end up with the one-iterator overload that only erases a single element.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top