闭包作为 C++ 中的参数和 return 类型

closure as argument and return type in C++

我努力实现一个 class 方法,该方法 returns 一个捕获 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

f1 函数标记为 returning auto:

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

然后你可以从 Bar class 模板制作,并在实例化时 使用 decltype 得到 return 类型的 f1:

template<class F>
class Bar {
};

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

因为你将 this 捕获到 lambda,它是非无状态的 lambda,不能默认构造,你不能只将 F 存储为普通成员变量。 为避免此问题,您可以使用智能指针来存储 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