这看起来类似于"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>
转换为参数类型std::function<T(int)>
,并考虑到v
的类型为std::vector<int>
,应该知道T
是int
吗?我想使用lambda表达式的全部原因就是它是一个表达式,因此我应该能够在函数调用参数列表中内联编写它,而不必给它起一个名称或将其分配给一个变量。 最佳答案
问题是,template argument deduction不考虑隐式转换(从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);
顺便说一句:如果您的编译器不支持
std::type_identity
,创建它并不难。有关
std::type_identity
在这里的工作方式,请参见non-deduced context:(强调我的)
关于c++ - 将lambda参数传递给没有中间变量的std::function参数,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/63558068/