Take the 2-minute tour ×

Suppose I want to have a function double adapter(double), is there a general way to compose it with a boost::function<double(...)> functor to produce another boost::function<double(...)> functor2 where functor2(...) == adapter(functor(...))? In particular, it would be cool if there was a way to do this without using C++11.

edit To clarify, I'm interested in knowing if there's a way to write something that can handle any boost::function<double(...)>, i.e. ones that have different length signatures without having to copy and paste multiple times for 1, 2, 3, etc. arguments.

share|improve this question
Supporting different number of arguments isn't a walk in the park in C++03. –  Luc Danton Sep 13 '12 at 19:48

1 Answer 1

up vote 2 down vote accepted

Without c++11, there are a significant number of complexities, including the varadic arguments and forwarding.

With C++11, it can be done, mostly by specializaing std::is_bind_expression. When this function object is used in a bind, it calls the function object that was stored with all of the arguments that were provided during the call to the bound function object. Note, this works with any function object, not just std::function.

This works with 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)...))



template<typename Func>
<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;
share|improve this answer

Your Answer


