使用Lambdas的模板类型扣除

时间:2014-07-30 13:47:16

标签: c++ templates lambda type-deduction

我面临的问题很简单。给出以下代码:

template <typename ReturnType, typename... Args>
auto CallIt( ReturnType( *method )( Args... ) )
{
    return method;
}

auto test = CallIt( [] ( int a, int b )
{
    return a > b;
} );

我得到的错误(使用VS13与2013年11月的CTP编译器)是:

Could not deduce template argument for ReturnType (__cdecl *)(Args...) from main::<lambda_e795bf5a030334e5fc8f3c26dbe00e0e>

我理解lambda不是函数指针,但是不捕获的lambda可以分配给匹配签名的函数指针。如果您明确指定模板参数,则此方法有效。我希望看到一种方法可以在不必明确指定模板参数的情况下工作。提前感谢您的帮助。

正如Marco A.提供的答案的评论中所指出的,可能有一个解决方案,使用lambda类上的一元+运算符,有效地将其转换为函数指针。但是,在请求的IDE /编译器组合中,我收到以下警告转为错误:

  

从“lambda [] bool(int a,int b) - &gt; bool”到内置类型的多个转换函数适用:

     

function“lambda [] bool(int a,int b) - &gt; bool :: operator bool(*)(int a,int b)()const”

     

function“lambda [] bool(int a,int b) - &gt; bool :: operator bool(*)(int a,int b)()const”

     

function“lambda [] bool(int a,int b) - &gt; bool :: operator bool(*)(int a,int b)()const”

     

function“lambda [] bool(int a,int b) - &gt; bool :: operator bool(*)(int a,int b)()const”

这个intellisense错误揭示了生成的编译错误:

  

错误C2593:'operator +'不明确

1 个答案:

答案 0 :(得分:4)

1)添加适当的trailing return type

2)如果您希望传递函数指针,请使用lambda conform to that

template <typename ReturnType, typename... Args>
auto CallIt( ReturnType( *method )( Args... ) ) -> ReturnType(*)(Args...)
{
    return method;
}

auto test = CallIt( +[] ( int a, int b )
{
    return a > b;
} );

Live Example


编辑:似乎MSVC2013出现了问题。作为一种解决方法,如果以下内容有效,您可以尝试:

#include <iostream>
#include <functional>
using namespace std;

template <typename ReturnType, typename... Args>
auto CallIt( std::function<ReturnType( Args... )> method ) -> std::function<ReturnType( Args... )>
{
    return method;
}

int main() {

    std::function<bool(int,int)> lambda = [] ( int a, int b ) { return a > b; };

    auto test = CallIt( lambda );
    cout << test(4,1);


    return 0;
}

Live Example