这个问题展示了如何使用函数谓词基于向量索引使用erase/remove_if.这在第一次调用函数时效果很好但是因为局部静态变量维持状态,在下次调用另一个向量时我会运气不好.所以我认为我可以使用一个带有可重用的私有变量的仿函数.除了第一个元素外,它主要起作用.remove_if使用仿函数混淆私有变量的初始化的方式是特定的
#include#include #include #include using namespace std; class is_IndexEven_Functor { public: is_IndexEven_Functor() : k(0) {} bool operator()(const int &i) { cout << "DEBUG: isIndexEvenFunctor: k " << k << "\ti " << i << endl; //// if(k++ % 2 == 0) { return true; } else { return false; } } private: int k; }; int main() { is_IndexEven_Functor a; a(0); a(1); a(2); a(3); vector v; v.push_back(0); v.push_back(1); v.push_back(2); v.push_back(3); cout << "\nBefore\n"; copy(v.begin(), v.end(), ostream_iterator (cout, " ")); cout << endl; is_IndexEven_Functor b; v.erase( remove_if(v.begin(), v.end(), b), v.end() ); cout << "\nAfter\n"; copy(v.begin(), v.end(), ostream_iterator (cout, " ")); cout << endl; return 0; }
这是输出:
DEBUG: isIndexEvenFunctor: k 0 i 0 DEBUG: isIndexEvenFunctor: k 1 i 1 DEBUG: isIndexEvenFunctor: k 2 i 2 DEBUG: isIndexEvenFunctor: k 3 i 3 Before 0 1 2 3 DEBUG: isIndexEvenFunctor: k 0 i 0 DEBUG: isIndexEvenFunctor: k 0 i 1 // why is k == 0 here ??? DEBUG: isIndexEvenFunctor: k 1 i 2 DEBUG: isIndexEvenFunctor: k 2 i 3 After 2
问题的关键是为什么k
在第二次调用函数时值等于0(以及如何修复它)?我猜这与remove_if有关,使用它作为临时对象或其他东西,但我真的不明白这意味着什么.
编辑:如果我能避免使用c ++ 11会很棒
是的,允许实现复制函数,因此如果函数具有可变状态,则可能会出现混乱行为.有几种方法可以解决这个问题.最简单的可能是使用a std::reference_wrapper
,可以使用以下std::ref
函数创建:
is_IndexEven_Functor b; v.erase( remove_if(v.begin(), v.end(), std::ref(b)), v.end() );
现在,实现不是复制函数对象,而是复制包装器,因此原始函数对象只有一个实例.
另一个选择是保持索引与函数分离:
class is_IndexEven_Functor { public: is_IndexEven_Functor(int &index) : k(index) {} . . . private: int &k; };
并像这样使用它:
int index = 0; is_IndexEven_Functor b(index); v.erase( remove_if(v.begin(), v.end(), b), v.end() );