std::bind with pointer to a function object

bind, c++, c++11, shared-ptr, variadic-templates

Solution

If we had a Standard function object for the dereference operator (much like `std::plus<T>` is for adding `T` with `T`) then we could involve a nested bind expression, but that is not the case -- plus we'd need a call operator because the usual substitutions that take place during the evaluation of nested bind expressions don't apply to the first argument! Your solution introduces an additional `std::function`, so I'm proposing some alternatives that don't.

Write your own call and dereference operators:

struct call {
    template<typename Callable, typename... Args>
    auto operator()(Callable&& callable, Args&&... args) const
    // don't use std::result_of
    -> decltype( std::declval<Callable>()(std::declval<Args>()...) )
    { return std::forward<Callable>(callable)(std::forward<Args>(args)...); }
};

struct dereference {
    template<typename T>
    auto operator()(T&& t) const
    -> decltype( *std::declval<T>() )
    { return *std::forward<T>(t); }
};

template<typename IndirectCallable, typename... Args>
auto indirect_bind(IndirectCallable&& f, Args&&... args)
-> decltype( std::bind(call {}
                       , std::bind(dereference {}, std::declval<IndirectCallable>())
                       , std::declval<Args>()... ) )
{ return std::bind(call {}
                   , std::bind(dereference {}, std::forward<IndirectCallable>(f))
                   , std::forward<Args>()... ); }

You can then do `auto g = indirect_bind(f, 0.0);`. Here's a proof-of-concept that also shows how placeholders are appropriately dealt with.

I mention the above solution because functors like `call` and `dereference` are useful bricks -- I personally have them among my tools. My preferred solution however would be to write a polymorphic functor that does the indirection and call in one go:

template<typename Indirect>
struct indirect_callable_type {
    // Encapsulation left as an exercise
    Indirect f;

    template<typename... Args>
    auto operator()(Args&&... args)
    // don't use std::result_of
    -> decltype( std::declval<Indirect&>()(std::declval<Args>()...) )
    { return f(std::forward<Args>(args)...); }

    template<typename... Args>
    auto operator()(Args&&... args) const
    // don't use std::result_of
    -> decltype( std::declval<Indirect const&>()(std::declval<Args>()...) )
    { return f(std::forward<Args>(args)...); }

    // Lvalue and rvalue *this version also left as an exercise
};

template<typename T>
indirect_callable_type<typename std::decay<T>::type>
make_indirect_callable(T&& t)
{ return { std::forward<T>(t) }; }

which you can, in fact, use as `auto g = std::bind(make_indirect_callable(f), 0.0);`.

I should mention that unlike your solution, those requires writing some types out-of-line. This is an unfortunate situation due to the inherent limitations of lambda expressions. Should you wish to stick with what you currently have, I have a minor recommendation that inside the lambda you `std::forward<Args>(args)...` the parameters. This might prove useful if you ever deal with move-only types.

Problem

Given a pointer to a function object: ``` std::shared_ptr<std::function<double(double)>> f; ``` is there a built-in construct in C++11 that allows be to use this pointer in a `std::bind` statement? For example: ``` std::function<double()> g = std::bind(built_in(f), 0.0); ``` What I am doing is to use variadic template as: ``` template<typename Ret, typename... Args> std::function<Ret(Args...)> get_fn(const std::shared_ptr<std::function<Ret(Args...)>>& f) { return [=](Args... args) -> Ret { return (*f)(args...); }; } ``` This allows me to write: ``` std::function<double()> g = std::bind(get_fn(f), 0.0); ``` Thanks in advance. Edit: I should have been clearer. I need to use the instance of the function object inside the shared pointer for optimization purposes.

Original source