为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C++
慕仙森 2019-08-12 16:47:51
如何使用模板将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()>([](){}));}
查看完整描述

3 回答

?
德玛西亚99

TA贡献1770条经验 获得超3个赞

如果std::function<T>没有显式指定模板参数,则不能将lambda函数对象作为类型的参数传递T。模板类型推导尝试将lambda函数的类型与std::function<T>在这种情况下它不能执行的类型相匹配- 这些类型不同。模板类型推导不考虑类型之间的转换。

如果您可以通过其他方式推断出类型,则有可能。您可以通过将函数参数包装在一个identity类型中来实现此目的,以便在尝试匹配lambda时不会失败std::function(因为依赖类型只是被类型推导忽略)并给出一些其他参数。

template <typename T>struct identity{
  typedef T type;};template <typename... T>void func(typename identity<std::function<void(T...)>>::type f, T... values) {
  f(values...);}int main() {
  func([](int x, int y, int z) { std::cout << (x*y*z) << std::endl; }, 3, 6, 8);
  return 0;}

这在你的情况下显然没用,因为你不想在以后传递这些值。

由于您不想指定模板参数,也不想传递可以推导出模板参数的其他参数,因此编译器将无法推断出std::function参数的类型。


查看完整回答
反对 回复 2019-08-12
?
慕少森

TA贡献2019条经验 获得超9个赞

您可以使用专门/回顾性演员。一旦你有这样的工具

#include <functional>using namespace std;template<typename T>struct memfun_type{
    using type = void;};template<typename Ret, typename Class, typename... Args>struct memfun_type<Ret(Class::*)(Args...) const>{
    using type = std::function<Ret(Args...)>;};template<typename F>typename memfun_type<decltype(&F::operator())>::type
FFL(F const &func){ // Function from lambda !
    return func;}

你可以FFL()对所有lambda类型说,将它们转换为正确的版本std::function

template <typename... Args> void Callback(std::function<void(Args...)> f){
    // store f and call later}int main(){
    Callback(FFL([](int a, float b){
        // do something
    }));

    return 0;}

显示


查看完整回答
反对 回复 2019-08-12
  • 3 回答
  • 0 关注
  • 1357 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信