将lambda参数传递给不带中间变量的std::函数参数



这看起来可能类似于;我不能将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)>——并且考虑到vstd::vector<int>类型,它应该知道Tint?我想使用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不参与模板参数演绎,但使用模板参数在其他地方推导或明确指定。如果模板参数仅在非推导的上下文中使用,并且没有明确指定,模板参数推导失败。

  1. 嵌套的名称说明符(作用域左侧的所有内容解析运算符::(合格id:

最新更新