I'm working on a problem in C++ that involves lots of subset and transformation operations on a large quantity of data. To that end, I've created a map function and something like list comprehensions. I've found that a bunch of the predicates I'm writing also have inverses, so I'd need to write:
template <typename type_t>
bool HasTenFoo(const type_t &t) {
return t.foo >= 10.0;
}
and
template <typename type_t>
bool DoesntHaveTenFoo(const type_t &t) {
return t.foo < 10.0;
}
Neither of those is a real example, but they're representative. I'm also using a fair number of functors like:
class HasEnoughFoo {
public:
HasEnoughFoo (double bar) { this->bar = bar; }
template<typename type_t>
bool operator()(const type_t &t) const { return t.foo >= bar; }
private:
double bar;
};
some of which should have inverses as well. Rather than duplicate code unnecessarily, I'd like to write a functor that takes a predicate as an argument and returns the (value of the) inverse of that predicate. My fist cut at one is below:
/* -- Returns the opposite of some other predicate -------------------------- */
template<typename predicate_t>
class Not {
public:
template <typename predicate_t>
Not(predicate_t *p) { predicate = p; }
template <typename type_t>
bool operator()(const type_t &t) const {
return !(*predicate)(t);
}
private:
predicate_t *predicate;
};
I would call that with something like:
new_list = old_list.subset(Not<HasEnoughFoo>(&HasEnoughFoo(10.0));
or
new_list = old_list.subset(Not<HasTenFoo>(&HasTenFoo));
That seems to work well when predicate_t
is a functor like HasEnoughFoo
, but fails when predicate_t
refers to a regular function like HasTenFoo
.
Visual Studio complains that 'HasTenFoo' is not a valid template type argument for parameter 'predicate_t'
. Is there any way to write a Not() predicate that will work with functors and functions or am I doomed to write dozens of predicates and their inverses as well?