Написание класса Predicate на C++
Пытался написать аналог класса Predicate в Java на C++. В итоге вышло какое-то убожество:
template <typename T>
class Predicate {
private:
Predicate<T> *other;
public:
virtual bool test(T &t) = 0;
Predicate<T> AND(Predicate<T> other);
Predicate<T> OR(Predicate<T> other);
Predicate<T> negate();
};
template<typename T>
Predicate<T> Predicate<T>::AND(Predicate<T> other) {
Predicate<T> *t = this;
class TmpPredicate : Predicate {
TmpPredicate() {
this->other = other;
}
bool test(T &t) {
return t->test(t) && other.test(t);
}
};
return TmpPredicate();
}
Остальные функции пока не реализовал.
В общем, это всё очень убого, но я понятия не имею, как это сделать нормально. Можете подсказать?
По задумке этот класс должен функционировать, как Predicate в Java. В идеальном варианте для работы с ним не нужно выделять динамическую память, работа с динамической памятью должна быть реализована в Predicate в его внутренней реализации.
Пример:
int main() {
Predicate<char> p([](char c) { return c == 'A'; });
Predicate<char> p2([](char c) { return c == 'B'; });
cout << p('b') << '\n'; // 0
cout << p.NOT()('a') << '\n'; // 1
cout << p.AND(p2)('A') << '\n'; // 0
cout << p.OR(p2)('B') << '\n'; // 1
cout << p.OR(p2).OR(p)('A') << '\n'; // 1
cout << p.OR(p2).OR(p).OR(p2)('a') << '\n'; // 0
}
Ответы (1 шт):
Автор решения: Имя Фамилия
→ Ссылка
Кто там говорил, что писать свой Predicate на C++ не целесообразно?
По мне так получилось очень целесообразно.
#include <memory>
template <typename T>
class Predicate {
using Tester = bool(*)(const T&);
enum Action {
Test,
And,
Or,
Not
};
class Data {
public:
Action action;
Predicate *first{}, *second{};
Tester tester{};
explicit Data(const Action &action) : action(action) {
}
~Data() {
delete first;
delete second;
}
};
shared_ptr<Data> data;
explicit Predicate(const Action &action) {
data = make_shared<Data>(action);
}
Predicate(const Predicate &p) : data(p.data) {
}
Predicate(const Predicate &p1, const Predicate &p2, const Action &action) : Predicate(action) {
data->first = new Predicate(p1);
data->second = new Predicate(p2);
}
public:
explicit Predicate(const Tester &tester) : Predicate(Test) {
data->tester = tester;
}
bool test(const T &t) const {
switch (data->action) {
case Test:
return data->tester(t);
case And:
return (*data->first).test(t) && (*data->second).test(t);
case Or:
return (*data->first).test(t) || (*data->second).test(t);
case Not:
return !(*data->first).test(t);
}
}
bool operator()(const T &t) const {
return test(t);
}
Predicate AND(const Predicate &other) const {
return Predicate(*this, other, And);
}
Predicate OR(const Predicate &other) const {
return Predicate(*this, other, Or);
}
Predicate NOT() const {
Predicate notThis(Not);
notThis.data->first = new Predicate(*this);
return notThis;
}
};