猿问

如何使用模板将lambda转换为std :: function

如何使用模板将lambda转换为std :: function

基本上,我希望能够做的是使用任意数量的任何类型的参数lambda并将其转换为std :: function。我尝试过以下方法,两种方法都不起作用。

std::function([](){});//Complains that std::function is missing template parameterstemplate <typename T> void foo(function<T> f){}foo([](){});//Complains that it cannot find a matching candidate

但是下面的代码确实有效,但它不是我想要的,因为它需要明确说明不适用于通用代码的模板参数。

std::function<void()>([](){});

我整个晚上一直在使用功能和模板,我只是想不出来,所以任何帮助都会非常感激。

正如评论中所提到的,我试图这样做的原因是因为我试图使用可变参数模板在C ++中实现currying。不幸的是,这在使用lambdas时非常糟糕。例如,我可以使用函数指针传递标准函数。

template <typename R, typename...A>void foo(R (*f)(A...)) {}void bar() {}int main() {
    foo(bar);}

但是,我无法弄清楚如何将lambda传递给这样的可变函数。为什么我对将泛型lambda转换为std :: function感兴趣是因为我可以执行以下操作,但最终要求我明确地将模板参数声明为std :: function,这正是我想要避免的。

template <typename R, typename...A>void foo(std::function<R(A...)>) {}int main() {
    foo(std::function<void()>([](){}));}


慕仙森
浏览 1358回答 3
3回答

德玛西亚99

如果std::function<T>没有显式指定模板参数,则不能将lambda函数对象作为类型的参数传递T。模板类型推导尝试将lambda函数的类型与std::function<T>在这种情况下它不能执行的类型相匹配- 这些类型不同。模板类型推导不考虑类型之间的转换。如果您可以通过其他方式推断出类型,则有可能。您可以通过将函数参数包装在一个identity类型中来实现此目的,以便在尝试匹配lambda时不会失败std::function(因为依赖类型只是被类型推导忽略)并给出一些其他参数。template&nbsp;<typename&nbsp;T>struct&nbsp;identity{ &nbsp;&nbsp;typedef&nbsp;T&nbsp;type;};template&nbsp;<typename...&nbsp;T>void&nbsp;func(typename&nbsp;identity<std::function<void(T...)>>::type&nbsp;f,&nbsp;T...&nbsp;values)&nbsp;{ &nbsp;&nbsp;f(values...);}int&nbsp;main()&nbsp;{ &nbsp;&nbsp;func([](int&nbsp;x,&nbsp;int&nbsp;y,&nbsp;int&nbsp;z)&nbsp;{&nbsp;std::cout&nbsp;<<&nbsp;(x*y*z)&nbsp;<<&nbsp;std::endl;&nbsp;},&nbsp;3,&nbsp;6,&nbsp;8); &nbsp;&nbsp;return&nbsp;0;}这在你的情况下显然没用,因为你不想在以后传递这些值。由于您不想指定模板参数,也不想传递可以推导出模板参数的其他参数,因此编译器将无法推断出std::function参数的类型。

慕少森

您可以使用专门/回顾性演员。一旦你有这样的工具#include&nbsp;<functional>using&nbsp;namespace&nbsp;std;template<typename&nbsp;T>struct&nbsp;memfun_type{ &nbsp;&nbsp;&nbsp;&nbsp;using&nbsp;type&nbsp;=&nbsp;void;};template<typename&nbsp;Ret,&nbsp;typename&nbsp;Class,&nbsp;typename...&nbsp;Args>struct&nbsp;memfun_type<Ret(Class::*)(Args...)&nbsp;const>{ &nbsp;&nbsp;&nbsp;&nbsp;using&nbsp;type&nbsp;=&nbsp;std::function<Ret(Args...)>;};template<typename&nbsp;F>typename&nbsp;memfun_type<decltype(&F::operator())>::type FFL(F&nbsp;const&nbsp;&func){&nbsp;//&nbsp;Function&nbsp;from&nbsp;lambda&nbsp;! &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;func;}你可以FFL()对所有lambda类型说,将它们转换为正确的版本std::functiontemplate&nbsp;<typename...&nbsp;Args>&nbsp;void&nbsp;Callback(std::function<void(Args...)>&nbsp;f){ &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;store&nbsp;f&nbsp;and&nbsp;call&nbsp;later}int&nbsp;main(){ &nbsp;&nbsp;&nbsp;&nbsp;Callback(FFL([](int&nbsp;a,&nbsp;float&nbsp;b){ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;do&nbsp;something &nbsp;&nbsp;&nbsp;&nbsp;})); &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;0;}显示
随时随地看视频慕课网APP
我要回答