Pass std algos predicates by reference in C++

…衆ロ難τιáo~ 提交于 2020-01-02 01:24:08

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!