remove_if 算法缺陷

/////////////////////////////////////////////////////// /// remove_if 算法缺陷 //////////////////// /// stl算法思想是先找到符合用户条件的第一个元素, /// 然后从这个元素的下一个元素开始把不符合用户 /// 条件的所有元素依次向第一个符合条件元素的 /// 位置排列copy(第一个元素被覆盖) /// /// 以下为remove_if的stl实现: template <class iter, class func_op> iter std::remove_if(iter beg, iter end, func_op op) { beg = find_if(beg, end, op); /// 第一次使用用户传入的op if(beg == end) { return beg; } else { iter next = beg; return remove_copy_if(++next, end, beg, op); /// 第二次使用用户传入的op } } /// 算法两次使用的用户的op,如果op中的条件是随着使用而变化的,这种算法就有可能达不到用户的要求,也就是错误的执行了用户的要求 /// 例子: /// 用户的目的是要删除第N个元素 class del_n { private: int n; int count; public: del_n(int value) : n(value), count(0) {} bool operator() (int) { return ++count == n; } }; /// 如果: vector<int> vec; for(int i = 1; i <= 9; ++i) { vec.push_back(i); } vector<int>::iterator it; /// 用户想把第三个元素删除 it = remove_if(vec.begin(), vec.end(), del_n(3)); vec.erase(it, vec.end()); /// 用户想得到结果是vec中的元素为1 2 4 5 6 7 8 9 /// 执行后,vec中的元素为1 2 4 5 7 8 9 /// /// 原因:remove_if算法中两次使用了op,为值传递,第一次使用是find_if, /// 找到了元素3的位置,但op.count的值还为0,然后从元素3的下一个位置开始, /// 使用了remove_copy_if,op.count为0,在remove_copy_if中从元素4开始到元素6时, /// op.count为3,符合条件,不进行copy,元素6就被从容器中删除。 /// /// 方案:直接使用remove_copy_if /// /// 建议:使用remove_if时,函数对象的operator()成员应声明为const /////////////////////////////////////////////////////// 

 

你可能感兴趣的:(算法,iterator,Class)