为什么当我们向std::函数发送lambda时,自动模板类型推导不起作用

why auto template type deduction does not work when we send a lambda to std::function?

本文关键字:类型 不起作用 lambda 我们 std 函数 为什么      更新时间:2023-10-16

为什么下面的代码不能编译?

template <class T>
void sort2( std::function<bool(T, T)> sort_func){
}
int main()
{
    sort2( [](int  l, int  r)->bool{return  r > l; });
}

    error C2784: 'void sort2(std::function<bool(T,T)>)' :
 could not deduce template argument for 'std::function<bool(T,T)>'

有没有办法使代码编译没有说模板参数明确?

sort2<int>( [](int  l, int  r)->bool{return  r > l; });

std::function是一个类型擦除类,它可以在其他类型中键入擦除lambda。

它与lambda的类型无关。

只有几个很好的理由可以推断类型擦除类的类型(主要是重载)。您可能需要的是一个概念要求子句或类似的东西,它将在c++ 1y之后出现,并且比推断std::function的类型更好地解决问题。

lambda不是std::function,它需要转换。因此,编译器无法找到与lambda完全匹配的

必须强制将lambda转换为函数或显式设置模板实参。

可以强制转换为函数,例如:

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))))

然后像这样使用:

sort2(to_function([](int  l, int  r)->bool{return  r > l; }));