Существует много впечатляющих библиотек Boost, таких как Повышение. Лямбда или Повышение. Финикс, которые имеют большое значение для превращения C++ на действительно функциональный язык. Но существует ли простой способ создать сложную функцию от каких-либо 2 или больше произвольных функций или функторов?
Если я имею: int f(int x)
и int g(int x)
, Я хочу сделать что-то как f . g
который статически генерировал бы новый функциональный объект, эквивалентный f(g(x)).
Это, кажется, возможно через различные методы, таково как обсужденные здесь. Конечно, можно объединить вызовы в цепочку к boost::lambda::bind
создать составной функтор. Но есть ли что-нибудь в Повышении, которое легко позволяет Вам брать какие-либо 2 или больше функции или функциональные объекты и комбинировать их для создания единственного составного функтора, подобного тому, как Вы сделали бы это на языке как Haskell?
Я не знаю ничего, что поддерживает желаемый синтаксис в настоящее время. Однако создать его будет несложно. Просто переопределите * для функторов (например, boost :: function <>), чтобы он возвращал составной функтор.
template < typename R1, typename R2, typename T1, typename T2 >
boost::function<R1(T2)> operator * (boost::function<R1(T2)> const& f, boost::function<R2(T2)> const& g)
{
return boost::bind(f, boost::bind(g, _1));
}
Не тестировалось, но я подозреваю, что это близко, если не работает из коробки.
Шаблон для них.
template<typename T1> class FunctorOne {
FunctorOne(T1 newt)
: t(newt) {}
void operator()() {
t();
}
T1 t;
};
template<> class FunctorOne<void> {
void operator()() {
}
};
template<typename T1> class FunctorTwo {
FunctorOne(T1 newt)
: t(newt) {}
void operator()() {
t();
}
T1 t;
};
template<> class FunctorTwo<void> {
void operator()() {
}
};
FunctorOne<FunctorTwo<FunctorOne<FunctorTwo<void>>>>> strangefunctionobject(FunctorTwo(FunctorOne(FunctorTwo()));
Рекомендуется отличное использование typedefs.
Редактировать: Упс. Оказывается, вывод типов в конструкторах - отстой. Я вернусь через минуту и расскажу кое-что, что действительно работает: P
Еще больше редактирования:
Если вам нужны только функторы, а не функциональноиды, вы можете просто создать новый instance, или даже просто используйте статические функции.
template<typename T1, typename T2> class FunctorOne {
public:
static bool Call() {
T1::Call(T2::Call());
return true;
}
};
template<> class FunctorOne<void, void> {
public:
static bool Call() {
}
};
template<typename T1> class FunctorTwo {
public:
static bool Call() {
T1::Call();
}
};
template<> class FunctorTwo<void> {
public:
static bool Call() {
}
};
bool haicakes = FunctorOne<FunctorTwo<void>, FunctorTwo<void>>::Call();
Это предполагает, что в любой данной функции вы можете обрабатывать каждую отдельную сигнатуру вручную. В этом отношении может помочь использование decltype с компилятором C ++ 0x.