c++templatesfunction-object

C++ Passing function objects as lvalues and/or rvalues


I have a class that should filter its contents according to a user-supplied predicate. The interface I am given prescribes taking a reference to the predicate:

class Test {
  vector<int> data;
public:
  template <class PREDTYPE>
  void filter(PREDTYPE& pred) {
    return;
  }
};

I am also given a piece of test code, which looks roughly like this:

class Filter {
public:
  bool operator()(int) const {
    return false;
  }
};

int main() {
  Test test;
  test.filter(Filter());
}

This doesn’t compile, saying cannot bind non-const lvalue reference of type 'Filter&' to an rvalue of type 'Filter'. If I change the testing code to

int main() {
  Test test;
  Filter filter;
  test.filter(filter);
}

it works, but this is up to the end user, and I have no control over their behaviour. I tried overloading the filter method, creating a version which would accept the predicate by value and then pass it on by reference, but this doesn’t compile either, with the message call of overloaded 'filter(Filter&)' is ambiguous.

Hence my question: is it possible to construct a filter that would accept both rvalues and lvalues of a predicate?


Solution

  • You might want to change your member function signature to

    template <class PREDTYPE> void filter(PREDTYPE&& pred)
    

    Here, the predicate is passed as a forwarding reference, which collapses to an lvalue reference for lvalues passed in an rvalue references to rvalues passed in.