A lambda is not a std::function
, it needs a conversion. so compiler cannot found an exact match with the lambda.
You have to force the conversion of the lambda to a function or explicitly set template argument.
You may force the conversion to function with something like:
namespace detail
{
template <typename T> struct function_traits {};
template <typename C, typename Res, typename...Args>
struct function_traits<Res (C::*)(Args...)const>
{
using result_type = Res;
using args_tuple_type = std::tuple<Args...>;
};
template <typename C, typename T> struct to_function;
template <typename C, typename... Ts> struct to_function<C, std::tuple<Ts...>>
{
using Ret = typename function_traits<decltype(&C::operator())>::result_type;
std::function<Ret (Ts...)> operator() (C c) const { return c; }
};
}
#define Return(res) decltype res { return res; }
template <typename Lambda>
auto to_function(Lambda lambda)
-> Return((detail::to_function<Lambda, typename detail::function_traits<decltype(&Lambda::operator())>::args_tuple_type>()(std::forward<Lambda>(lambda))))
And then use it like:
sort2(to_function([](int l, int r)->bool{return r > l; }));