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?
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.