将lambda参数传递给没有中间变量的std :: function参数

问题描述

这看起来类似于"I cannot pass lambda as std::function",但实际上是通过值传递std::function参数,因此该问题不适用。我定义了以下函数。

template<typename T>
std::vector<T> countSort(const std::vector<T> &v,std::function<int(T)> keyFunc,int n);

第二个参数是std::function,它将T映射到int(按值传递)。

调用此函数时,我想使用一个lambda表达式,如下所示:

std::vector<int> v;
[...]
v = countSort(v,[](int x) { return x; },10);

但是模板自变量推导失败,因为“ main()::<lambda(int)>并非源自std::function<int(T)>”。如果我指定了模板参数,或者为lambda表达式引入了std::function类型的中间变量,它就会起作用:

std::function<int(int)> lambda = [](int x) { return x; };
v = countSort(v,lambda,10);

为什么我不能做前者?我给编译器完全相同的信息。如果在将其分配给变量时能够将类型lambda<int>的值转换为std::function<int(int)>,为什么不能将其从lambda<int>直接转换为参数类型{{ 1}} –考虑到std::function<T(int)>v类型,应该知道std::vector<int>T吗?我想使用lambda表达式的全部原因就是,它是一个 expression ,因此我应该能够在函数调用参数列表中内联编写它,而不必给它起名称或赋值变成变量。

解决方法

问题是,template argument deduction不考虑隐式转换(从lambda到std::function),这导致第二个函数参数T上的keyFunc推导为失败。

类型推导不考虑隐式转换(上面列出的类型调整除外):这是overload resolution的工作,以后会发生。

您可以使用std::type_identity(自C ++ 20起)从推论中排除第二个函数参数。例如

template<typename T>
std::vector<T> countSort(const std::vector<T> &v,std::function<int(std::type_identity_t<T>)> keyFunc,int n);

顺便说一句:如果您的编译器不支持std::type_identity,那么编写一个就不难了。

有关std::type_identity在这里的工作方式,请参见non-deduced context

(重点是我的)

在以下情况下,类型,模板和非类型值 用于撰写P 不参与模板参数 推导,而是使用 推导到其他地方或明确指定。如果模板参数是 仅在非推论上下文中使用且未明确指定, 模板参数推导失败。

  1. 嵌套名称说明符(范围左侧的所有内容 解析运算符::)的类型使用 qualified-id

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...