首页 > 解决方案 > 带有模板参数的 Lambda 函数,而不是函数参数

问题描述

为什么第一个调用不编译?

auto get1 = []<int B>() { return B; };
auto get2 = []<typename B>(B b) { return b; };

int main()
{
    get1<5>(); // error: no match for operator<
    get2(5);   // ok
}

我使用它的原因是代码中重复多次的表达式。

当然我可以使用一个真正的函数模板,但我只是好奇为什么。

标签: c++templateslambdac++20

解决方案


如果您考虑等效类类型对您的外观来说,这将更容易理解get1

struct get1_t {
    template <int B> operator()() const { return B; }
};

get1_t get1;

get1<5>(); // error

您正在尝试向调用运算符提供显式模板参数,但从语法上讲,您正在做的事情看起来像是为get1自己提供模板参数(即,好像get1是一个变量模板)。为了为呼叫操作员提供模板参数,您必须直接执行此操作:

get1.operator()<5>(); // ok

或重组呼叫操作员以采取可推论的方式:

template <int B> struct constant { };
get1(constant<5>{});

或者将整个事物重构为实际上是它看起来像的变量模板:

template <int B>
auto get1 = [] { return B; };

现在,get1<5>它本身就是一个 lambda,你正在调用它。也就是说,我们有一个变量模板 lambda,它本身不是模板,而不是带有调用运算符模板的 lambda。


推荐阅读