Композиция буст-функции

Предположим, я хочу иметь функцию double adapter(double)Есть ли общий способ составить его с boost::function<double(...)> functor производить другой boost::function<double(...)> functor2 где functor2(...) == adapter(functor(...))? В частности, было бы здорово, если бы был способ сделать это без использования C ++ 11.

редактировать Чтобы уточнить, мне интересно знать, есть ли способ написать что-то, что может обрабатывать любые boost::function<double(...)>то есть те, которые имеют подписи разной длины, без необходимости копировать и вставлять несколько раз для аргументов 1, 2, 3 и т. д.

1

Решение

Без c ++ 11 существует значительное количество сложностей, в том числе неординарные аргументы и переадресация.

С C ++ 11 это можно сделать, в основном, за счет специализации std::is_bind_expression, Когда этот функциональный объект используется в привязке, он вызывает функциональный объект, который был сохранен со всеми аргументами, которые были предоставлены во время вызова связанного функционального объекта. Обратите внимание, это работает с любым функциональным объектом, а не только std::function,

Это работает с GCC 4.7.

#include <functional>
#include <utility>
#include <type_traits>

namespace detail
{
template<typename Func>
struct compose_functor
{

Func f;

explicit compose_functor(const Func& f) : f(f) {};

template<typename... Args>
auto operator()(Args&&... args) const -> decltype(f(std::forward<Args>(args)...))
{
return f(std::forward<Args>(args)...);
}

};

}

template<typename Func>
detail::compose_functor
<Func> compose(Func f)
{
return detail::compose_functor<Func>(f);
}namespace std
{
template<typename T>
struct is_bind_expression< detail::compose_functor<T> > : true_type {};
}
#include <numeric>

int adapter(double d)
{
return (int)d;
}

int main()
{
std::function<int(double)> f1 = std::bind(adapter, compose(std::negate<double>()));
std::function<int(double, double)> f2 = std::bind(adapter, compose(std::plus<double>()));

// 1.5 -> -1.5 -> -1
std::cout << f1(1.5) << std::endl;
// 2.3+4.5 = 6.8 -> 6
std::cout << f2(2.3, 4.5) << std::endl;
}
2

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector