Я работаю над проблемой в C ++, которая включает в себя множество операций с подмножествами и преобразованиями для большого количества данных. Для этого я создал функцию карты и что-то вроде списочного понимания. Я обнаружил, что куча предикатов, которые я пишу, также имеют инверсии, поэтому мне нужно написать:
template <typename type_t>
bool HasTenFoo(const type_t &t) {
return t.foo >= 10.0;
}
и
template <typename type_t>
bool DoesntHaveTenFoo(const type_t &t) {
return t.foo < 10.0;
}
Ни один из них не является реальным примером, но они репрезентативны. Я также использую достаточное количество функторов, таких как:
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;
};
некоторые из которых должны иметь и обратные. Вместо ненужного дублирования кода, я хотел бы написать функтор, который принимает предикат в качестве аргумента и возвращает (значение) обратное этому предикату. Мой кулак ниже одного:
/* -- 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;
};
Я бы назвал это чем-то вроде:
new_list = old_list.subset(Not<HasEnoughFoo>(&HasEnoughFoo(10.0));
или
new_list = old_list.subset(Not<HasTenFoo>(&HasTenFoo));
Кажется, это хорошо работает, когда predicate_t
является функтором, подобным HasEnoughFoo
, но не работает, когда predicate_t
относится к обычной функции, такой как HasTenFoo
.
Visual Studio жалуется, что 'HasTenFoo' is not a valid template type argument for parameter 'predicate_t'
. Есть ли способ написать предикат Not (), который будет работать с функторами и функциями, или я обречен на написание десятков предикатов и их инверсий?