views:

134

answers:

1

C++0x has deprecated the use of old binders such as bind1st and bind2nd in favor of generic std::bind. C++0x lambdas bind nicely with std::bind but they don't bind with classic bind1st and bind2nd because by default lambdas don't have nested typedefs such as argument_type, first_argument_type, second_argument_type, and result_type. So I thought std::function can serve as a standard way to bind lambdas to the old binders because it exposes the necessary typedefs.

However, using std::function is hard to use in this context because it forces you to spell out the function-type while instantiating it.

auto bound = 
  std::bind1st(std::function<int (int, int)>([](int i, int j){ return i < j; }), 10); // hard to use
auto bound = 
  std::bind1st(std::make_function([](int i, int j){ return i < j; }), 10); // nice to have but does not compile.

I could not find a convenient object generator for std::function. Something like std::make_fuction would be nice to have. Does such a thing exist? If not, is there any other better way of binding lamdas to the classic binders?

+1  A: 

Never tried to do such thing, and I don't have the time to provide a full answer, but I guess that something could be done with Boost.FunctionTypes.

Here's a rough, incomplete and untested draft to give you an idea:

template <typename T>
struct AdaptedAsUnary : T
{
    namespace bft = boost::function_types;
    namespace bmpl = boost::mpl;

    typedef typename bft::result_type<T>::type result_type;
    typedef typename bmpl::front<typename bft::parameter_types<T>::type>::type argument_type;

    AdaptedAsUnary(T t) : T(t) {}
};

template <typename T>
AdaptedAsUnary<T>
AdaptAsUnary(T t)
{
    return AdaptedAsUnary<T>(t);
}
Éric Malenfant
This is a neat solution. Inheriting from a lambda-type is new to me and works nicely on g++ 4.5. Although as of today, boost::function_types (1.42) does not support lambdas as a built-in callable type, I could find my way out. In future, when they support it (I hope), this solution can be used as is. For now, I used the answer for http://stackoverflow.com/questions/2562320/specializing-a-template-on-a-lambda-in-c0x as a substitute for the introspection capabilities of boost::function_types. Using those function_traits for lambdas, multiple inheritance from T and std::unary_function works.
Sumant