哪个顺序用于堆栈或堆栈变量创建

时间:2014-03-09 22:09:40

标签: c++ stl-algorithm stdlist remove-if

我有这段代码:

#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”。我预计它会打印出“75”,因为P结构的operator()在其参数没有除以3的余数时返回true。这就是'6'和'9'的情况(两个元素)七分之一)。 我错过了什么吗?

感谢。

3 个答案:

答案 0 :(得分:1)

引用http://www.cplusplus.com/reference/algorithm/remove_if/

  

该函数不能改变包含元素范围的对象的属性(即,它不能改变数组或容器的大小):通过用下一个元素替换pred返回true的元素来完成删除它没有,并通过将迭代器返回到应该被视为新的过去元素的元素来发出缩短范围的新大小。

换句话说,它重新排列给定范围内的元素,以便所有未删除的元素都在开头,然后返回一个迭代器,刚好超过未删除部分的末尾。但它不能删除任何元素,因为它对底层容器一无所知。

答案 1 :(得分:1)

是否有可能std :: remove_if返回结果列表?

答案 2 :(得分:1)

remove / remove_if重新排序一个序列,它不会修改它。迭代器无法访问或了解它们来自的容器。您需要将结果传递给合适的erase容器成员:

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

不要忘记第二个l.end(),以便获得erase的双迭代器重载,从而擦除整个范围。如果你忘了它,你最终会得到只能擦除单个元素的one-iterator重载。