Predicates

Gotchas (Effective STL also mentions this gotcha):

1) Predicates should be always stateless.
2) The operator() member function should be always const


class Nth { // function object that returns true for the nth call
private:
    int nth; // call for which to return true
    int count; // call counter
public:
    Nth (int n) : nth(n), count(0) {  // having state indicates problem
    }
    bool operator() (int) {  // non-const member operation() function indicates problem
        return ++count == nth;
    }
};

list<int> coll = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
list<int>::iterator pos;
pos = remove_if(coll.begin(),coll.end(), // range
Nth(3)); // remove criterion
coll.erase(pos,coll.end());

// May have other output depending on the STL implementation.
Output: 1 2 4 5 7 8 9 10

Root cause:
The algorithm uses find_if() to find the first element that should be removed. However, the
algorithm then uses a copy of the passed predicate op to process the remaining elements, if any.
Here, Nth in its original state is used again and also removes the third element of the remaining
elements, which is in fact the sixth element.

template <typename ForwIter, typename Predicate>
ForwIter std::remove_if(ForwIter beg, ForwIter end, Predicate op)
{
    beg = find_if(beg, end, op);  // find_if takes a copy of 'op'
    if (beg == end) {
        return beg;
    }
    else {
        ForwIter next = beg;
        return remove_copy_if(++next, end, beg, op);  // here 'op' still have the original state.
    }
}

Solution: Use lambdas
int count=0; // call counter
pos = remove_if(coll.begin(),coll.end(),   [&count] (int) {
                                                                        return ++count == 3;
                                                                    });

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值