闭包作为参数,在C ++中为返回类型

问题描述 投票:0回答:1

我难以实现一个类方法,该方法返回一个捕获this的闭包(在示例Foo::f1中)。这个想法是在Bar中将其用作回调。

第一个障碍是我没有弄清楚如何在using语句中指定闭包类型。

#include <iostream>

class Foo {
 public:
  Foo() = default;
  ~Foo() = default;

  // don't know what the correct type specification is
  //using fptr = [](int)->int;
  //using fptr = int operator()(int);
  //using fptr = int (*)();
  typedef int (*fptr)(int);

  fptr f1(void) {
    return [this](int k)->int { return k * this->x_; };
  }

 private:
  int x_ = 2;
};

class Bar {
 public:
  Bar() = default;
  ~Bar() = default;
  void setfun(Foo::fptr f) { f_ =  f; }
  void callfun() {
    std::cout << "result = " << f_(8) << std::endl;
  }
 private:
  Foo::fptr f_;
};


int main(int, char **) {
  Foo foo;
  Bar bar;
  bar.setfun(foo.f1());
  bar.callfun();
  return 0;
}

vg

lambda callback closures c++17 using
1个回答
0
投票

f1标记为返回auto

  auto f1(void) 
  {
    return [this](int k)->int { return k * this->x_; };
  }

然后您可以从Bar类模板中以及在隐含使用decltype获取f1的返回类型:

template<class F>
class Bar {
};

Foo foo;
Bar< decltype( std::declval<Foo>().f1() ) > bar;

因为您将this捕获到lambda,所以它是非无状态lambda,不能默认构造。为避免此问题,您可以使用智能指针来存储F,例如unique_ptr

template<class F>
class Bar  {
   void setfun(F f) { f_ =  std::make_unique<F>(f); }
   std::unique_ptr<F> f_;
};

完整的代码是:

class Foo {
 public:
  Foo() = default;
  ~Foo() = default;

  auto f1(void) 
  {
    return [this](int k)->int { return k * this->x_; };
  }

 private:
  int x_ = 2;
};

template<class F>
class Bar 
{
 public:
  Bar() = default;
  ~Bar() = default;

   void setfun(F f) { f_ =  std::make_unique<F>(f); }

   void callfun() 
   {
     std::cout << "result = " << (*f_)(8) << std::endl;
   }
 private:
  std::unique_ptr<F> f_;
};


int main(int, char **)  {
  Foo foo;
  Bar< decltype( std::declval<Foo>().f1() ) > bar;

  bar.setfun(foo.f1());
  bar.callfun();

Full demo

© www.soinside.com 2019 - 2024. All rights reserved.