【问题标题】:Template Type Deduction with Lambdas使用 Lambda 进行模板类型推导
【发布时间】:2014-09-22 04:42:11
【问题描述】:

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

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. 提供的答案的 cmets 中所指出的,使用 lambda 类上的一元 + 运算符可能会解决此问题,有效地将其转换为函数指针。但是,在请求的 IDE/编译器组合中,我收到以下警告错误:

有多个从 "lambda []bool (int a, int b)->bool" 到内置类型的转换函数:

function "lambda []bool (int a, int b)->bool::operator bool (*)(int a, int b)() const"

function "lambda []bool (int a, int b)->bool::operator bool (*)(int a, int b)() const"

function "lambda []bool (int a, int b)->bool::operator bool (*)(int a, int b)() const"

function "lambda []bool (int a, int b)->bool::operator bool (*)(int a, int b)() const"

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

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

【问题讨论】:

  • 模板函数没有类型推导,从 Lambda 转换为函数指针可能涉及一些隐含的转换。有关解决此问题的方法,请参阅 this 上一个问题。

标签: c++ templates lambda type-deduction


【解决方案1】:

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

【讨论】:

  • 您能详细说明为什么这里需要前缀+ 运算符吗?
  • @Chnossos 它在发布的链接中进行了解释:它允许转换 lambda -> 函数指针。
  • 我问的时候没有链接。感谢您提供。
  • 这是我第一次听说 lambda 上的 + 前缀,我在使用指定的 IDE/编译器时遇到了麻烦。错误显示operator+ is ambiguous
  • @WilliamCustode:嗯,它不应该......它适用于 gcc 和 clang,所以我想这是另一个 VS 怪癖。
猜你喜欢
  • 1970-01-01
  • 2014-05-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多