接受lambda作为函数参数并提取返回类型

Ale*_*man 2 c++ lambda templates c++11

我需要接受lambda函数作为参数并找出它的返回类型.到目前为止,我无法想出任何可行的方法.这是一个例子:

template <typename T1, typename T2>
T1 foo(T2 arg, std::function<T1(T2)> f)
{
    return f(arg);
}

...

int n = foo(3, [](int a){ return a + 2; });   <-- ERROR!
Run Code Online (Sandbox Code Playgroud)

怎么做到呢?Boost解决方案也可以.

Rap*_*ptz 6

您不应该std::function作为参数传递.它有一些开销,因为它使用类型擦除来存储任何类型的可调用,如函数指针,仿函数,lambda(它们只是一个自动生成的函子)等.相反,你应该只模板化函数类型.然后,您可以使用尾随返回类型来确定函数的返回类型:

template <typename T, typename Function>
auto foo(T arg, Function f) -> decltype(f(arg))
{
    return f(arg);
}
Run Code Online (Sandbox Code Playgroud)


Pra*_*ian 5

An std::function和lambda不一样,它们是不同的类型.前者是可以存储任何类型的可调用对象的容器,而后者是可调用对象.为std::function作品分配lambda 因为std::function有一个执行必要转换的构造函数.但是模板参数推导不是这种情况,它需要完全匹配,并且不考虑用户定义的转换.这就是你的代码无法编译的原因.

解决方案很简单,正如Rapptz的回答所述,修改foo以将可调用作为模板参数.

template <typename Arg, typename Func>
auto foo(Arg arg, Func f)
    -> decltype(f(arg))
{
    return f(arg);
}
Run Code Online (Sandbox Code Playgroud)