当lambda作为参数传入时,Deduce模板参数

时间:2014-01-20 22:59:28

标签: c++ c++11 lambda

我正在尝试编写函数func,以便编译器可以推导出模板参数,它在我传入std::function时有效,但不能与lambdas一起使用:

template<typename TResult>
TResult func(std::function<TResult()> f)
{
    return TResult();
}

int main()
{
                                // Visual Studio 2013
    int result = func([]() {    // error: 'TResult func(std::function<TResult(void)>)' : could not deduce template argument for 'std::function<TResult(void)>' from 'main::<lambda_d9d7854806072a2cb711f56185602ccb>'
        return 100;
    });

    std::function<int()> testFunc = []() {
        return 100;
    };
    int result2 = func(testFunc); // this works

    return 0;
}

是否可以推导出lambda的模板参数,以便该行编译?而不是写func<int>([](){ return 100; });我想写func([](){ return 100; });

4 个答案:

答案 0 :(得分:5)

我迟到了一点:) 有一个没有std::function

的解决方案
template<typename Class, typename R, typename... Args>
R resultType(R (Class::*)(Args...) const)
{
    return R();
}

template<typename Class, typename R, typename... Args>
R resultType(R (Class::*)(Args...))
{
    return R();
}

template<typename Functor>
auto func(Functor f) -> decltype(resultType(&Functor::operator()))
{
    return resultType(&Functor::operator());
}

答案 1 :(得分:4)

我无法看到如何立即执行此操作,但您可以在间接中执行此操作:

template <typename TResult>
TResult func(std::function<TResult()> f) {
    return TResult();
}

template <typename Fun>
auto func(Fun f) -> decltype(f()) {
    return func(std::function<decltype(f())>(f));
}

答案 2 :(得分:2)

至少如果我理解了意图,我相信你可以这样做:

template <class F>
auto foo(F &&f) -> decltype(f()) {
    typedef decltype(f()) ret_type;
    return ret_type();
}

...或者如果您不想使用typedef

template <class F>
auto foo(F &&f) -> decltype(f()) {
    return decltype(f())();
}

完整程序,比较使用情况和结果:

#include <functional>
#include <iostream>

template <class F>
auto foo(F &&f) -> decltype(f()) {
    return decltype(f())();
}

template<typename TResult>
TResult func(std::function<TResult()> f) {
    return TResult();
}

int main() {
   std::cout << foo([]() { return 100; })<<"\n";

    std::function<int()> testFunc=[]() { return 100; };
    std::cout << func(testFunc) <<"\n"; // this works

    return 0;
}

结果:

0
0

答案 3 :(得分:1)

不,你不能在这里使用std::function,编译器不能推断出它的类型参数。

您应该将参数传递为TFunction