Ana*_*and 1 c++ lambda templates std-function template-argument-deduction
这可能看起来类似于"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);
Run Code Online (Sandbox Code Playgroud)
第二个参数是std::function映射T到int(按值传递)的 。
在调用这个时,我想使用一个 lambda 表达式,如下:
std::vector<int> v;
[...]
v = countSort(v, [](int x) { return x; }, 10);
Run Code Online (Sandbox Code Playgroud)
但是模板参数推导失败,因为“main()::<lambda(int)>不是从std::function<int(T)>”派生的。如果我指定模板参数,或者如果我std::function为 lambda 表达式引入一个类型的中间变量,它确实有效:
std::function<int(int)> lambda = [](int x) { return x; };
v = countSort(v, lambda, 10);
Run Code Online (Sandbox Code Playgroud)
为什么我不能做前者?我给编译器完全相同的信息;如果它能够类型的值转换lambda<int>,以std::function<int(int)>将其分配给一个变量时,为什么不能直接从转换lambda<int>参数类型,这是std::function<T(int)>-和考虑到v的类型的std::vector<int>,应该知道T的int?我想使用 lambda 表达式的全部原因正是它是一个表达式,所以我应该能够将它内联写入函数调用参数列表中,而不必给它一个名称或将它分配给一个变量。
问题是,模板参数推导不考虑隐式转换(从 lambda 到std::function),这会导致T第二个函数参数的推导keyFunc失败。
类型推导不考虑隐式转换(上面列出的类型调整除外):这是重载解析的工作,稍后会发生。
您可以使用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);
Run Code Online (Sandbox Code Playgroud)
BTW:如果你的编译器不支持 std::type_identity,那么制作一个并不难。
关于std::type_identity这里的工作原理,请参阅非推断上下文:
(强调我的)
在以下情况下,用于组合的类型、模板和非类型值
P不参与模板参数推导,而是使用在其他地方推导或明确指定的模板参数。如果模板参数仅在非推导上下文中使用且未明确指定,则模板参数推导失败。
- 使用限定 id指定的类型的嵌套名称说明符(范围解析运算符左侧的所有内容
::) :
| 归档时间: |
|
| 查看次数: |
206 次 |
| 最近记录: |