• remove_if的问题


      

    #include<iostream>
    #include<list>
    #include<algorithm>
    #include"PRINT_ELEMENTS.h"
    
    using namespace std;
    
    class Nth{
        private:
            int nth;
            int count;
        public:
            Nth(int n):nth(n),count(0){
            }
            bool operator()(int){
                return ++count==nth;
            }
    };
    
    int main(int argc, char **argv)
    {
        list<int> coll;
        for(int i=1; i<=9;++i){
            coll.push_back(i);
        }
        PRINT_ELEMENTS(coll,"initialized: ");
        
        list<int>::iterator pos = remove_if(coll.begin(),coll.end(),Nth(3));
        coll.erase(pos, coll.end());
        PRINT_ELEMENTS(coll, "remove_if: ");
        return 0;
    }

     //PRINT_ELEMENTS.h

    template<typename T>
    inline void PRINT_ELEMENTS(const T& coll, const char* optcstr="")
    {
        typename T::const_iterator pos;
        std::cout << optcstr << std::endl;
        for(pos = coll.begin(); pos != coll.end(); ++pos)
            std::cout << *pos << " ";
        std::cout << std::endl;
    }

    输出结果:

    initialized:
    1 2 3 4 5 6 7 8 9
    remove_if:
    1 2 4 5 7 8 9

    而不是:

    initialized:
    1 2 3 4 5 6 7 8 9
    remove_if:
    1 2 4 5 6 7 8 9

    此处是remove_if的问题:

    remove_if源代码为:

    template<typename ForwIter, typename Predicate>
    ForwIter remove_if(ForwIter beg, ForwIter end, Predicate op)
    {
        beg=find_if(beg, end, op)
        
        if(beg == end)
        {
            return beg;
        }
        else
        {
            ForwIter next = beg;
            return remove_copy_if(++next, end, beg, op);
        }
    }

    这里find_if调用op是复制了一个op的副本,所以当remove_copy_if再次调用op是用重新计数了,所以也把6删除了;

    可以用:

    #include<iostream>
    #include<list>
    #include<algorithm>
    #include"PRINT_ELEMENTS.h"
    
    using namespace std;
    
    class Nth{
        private:
            int nth;
            int count;
        public:
            Nth(int n):nth(n),count(0){
            }
            bool operator()(int){
                return ++count==nth;
            }
    };
    
    template<typename ForwIter, typename Predicate>
    ForwIter remove_if_my(ForwIter beg, ForwIter end, Predicate op)
    {
        while(beg != end && !op(*beg))
        {
            ++beg;
        }
        
        if(beg == end)
        {
            return beg;
        }
        else
        {
            ForwIter next = beg;
            return remove_copy_if(++next, end, beg, op);
        }
    }
    int main(int argc, char **argv)
    {
        list<int> coll;
        for(int i=1; i<=9;++i){
            coll.push_back(i);
        }
        PRINT_ELEMENTS(coll,"initialized: ");
        
        list<int>::iterator pos = remove_if_my(coll.begin(),coll.end(),Nth(3));
        coll.erase(pos, coll.end());
        PRINT_ELEMENTS(coll, "remove_if: ");
        return 0;
    }

    这样避去用find_if,所以就可以了。

    参考:《C++标准程序库》P302

  • 相关阅读:
    java 学习 —— AWT布局组件
    Java 学习 ——网络与通信
    Java 学习————线程直接通信
    Java 学习————多线程同步
    改善PHP开发方式的5种方法
    grep在linux操作系统php,pytho等开发中的应用
    CSS border边框属性教程(color style)
    css输入框文字点击消失输入文字颜色变深JQ特效
    DIVCSS5模块 上标题下简介列表DIV CSS布局
    DIV CSS position绝对定位absolute relative教程篇
  • 原文地址:https://www.cnblogs.com/yi-meng/p/remove_if.html
Copyright © 2020-2023  润新知