问题
I am trying to remove elements from a std::list
and keep some stats of deleted elements.
In order to do so, I use the remove_if function from the list, and I have a predicate. I would like to use this predicate to gather statistics. Here is the code for the predicate:
class TestPredicate
{
private:
int limit_;
public:
int sum;
int count;
TestPredicate(int limit) : limit_(limit), sum(0), count(0) {}
bool operator() (int value)
{
if (value >= limit_)
{
sum += value;
++count; // Part where I gather the stats
return true;
}
else
return false;
}
};
And here is the code for the algo:
std::list < int > container;
container.push_back(11);
TestPredicate pred(10);
container.remove_if(pred)
assert(pred.count == 1);
Unfortunately, the assertion is false because the predicate is passed by value. Is there a way to force it to be passed by reference ?
回答1:
Pass a reference wrapper, available from <functional>
:
container.remove_if(std::ref(pred));
If you only have C++98/03 but your compiler has TR1, you can use <tr1/functional>
and std::tr1::ref
if you make a small amendment to your predicate:
#include <tr1/functional>
class TestPredicate : public std::unary_function<int, bool>
{ //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// ...
}
container.remove_if(std::tr1::ref(pred));
If all else fails, then you can hack up a manual solution with relative ease:
struct predref
{
TestPredicate & p;
bool operator()(int n) { return p(n); }
predref(TestPredicate & r) : p(r) { }
};
container.remove_if(predref(pred));
回答2:
The functors passed to the algorithms can be copied inside the algorithm an indeterminate number of times, so you cannot store state directly in the functor. You can, on the other hand, store the state outside of the functor, by using a pointer or reference to some external state structure.
来源:https://stackoverflow.com/questions/8313370/pass-std-algos-predicates-by-reference-in-c