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 ?
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));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With