使用 Lambda 进行模板类型推导

Wil*_*ode 5 c++ lambda templates type-deduction

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

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

auto test = CallIt( [] ( int a, int b )
{
    return a > b;
} );
Run Code Online (Sandbox Code Playgroud)

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

无法从 main::<lambda_e795bf5a030334e5fc8f3c26dbe00e0e> 推断出 ReturnType (__cdecl *)(Args...) 的模板参数

据我了解,lambda 不是函数指针,但未捕获的 lambda 可以分配给匹配签名的函数指针。如果您显式指定模板参数,则此方法有效。我希望看到一种无需显式指定模板参数即可实现此功能的方法。预先感谢您的帮助。

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

从“lambda []bool (int a, int b)->bool”到内置类型的不止一个转换函数适用:

函数“lambda []bool (int a, int b)->bool::operator bool (*)(int a, int b)() const”

函数“lambda []bool (int a, int b)->bool::operator bool (*)(int a, int b)() const”

函数“lambda []bool (int a, int b)->bool::operator bool (*)(int a, int b)() const”

函数“lambda []bool (int a, int b)->bool::operator bool (*)(int a, int b)() const”

此智能感知错误揭示了生成的编译错误,指定:

错误 C2593:“运算符 +”不明确

Mar*_* A. 4

1) 添加适当的尾随返回类型

2) 如果你想传递一个函数指针,让 lambda符合这个要求

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

auto test = CallIt( +[] ( int a, int b )
{
    return a > b;
} );
Run Code Online (Sandbox Code Playgroud)

实例


编辑: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;
}
Run Code Online (Sandbox Code Playgroud)

实例

  • @WilliamCustode:嗯,它不应该......它与 gcc 和 clang 一起工作,所以我想这是另一个 VS 怪癖。 (2认同)