这看起来可能类似于;我不能将lambda作为std::function"传递;,但我实际上是按值传递std::function
参数,所以这个问题不适用。我定义了以下函数。
template<typename T>
std::vector<T> countSort(const std::vector<T> &v, std::function<int(T)> keyFunc, int n);
第二个参数是将T
映射到int
(通过值传递(的std::function
。
在调用此函数时,我希望使用lambda表达式,如下所示:
std::vector<int> v;
[...]
v = countSort(v, [](int x) { return x; }, 10);
但是模板参数推导失败了,因为";CCD_ 5不是从CCD_;。如果我指定了模板参数,或者为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>
转换为参数类型,即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);
BTW:如果您的编译器不支持std::type_identity
,那么制作一个并不困难。
关于std::type_identity
在这里是如何工作的,请参阅非推导上下文:
(重点矿井(
在以下情况下用于组成
P
不参与模板参数演绎,但使用模板参数在其他地方推导或明确指定。如果模板参数仅在非推导的上下文中使用,并且没有明确指定,模板参数推导失败。
- 嵌套的名称说明符(作用域左侧的所有内容解析运算符
::
(合格id: