c++ - 将回调函数打包到模板类中

标签 c++ templates

我正在尝试制作一个回调函数结构,我可以放置一个通用函数及其将接收的所有参数,以便在执行期间的任何时候我都可以调用它。

对我来说,它看起来像这样:

template <typename T, typename... targs>
class CallbackFunction {
private:
    targs... args;
    std::function<T(targs...)> fun;

public:
    CallbackFunction(std::function<T(targs...)> fun, targs... args) : fun(fun), args(args) {}

    T call () {
        return this->fun(this->args);
    }
};

这样我就可以做这样的事情:

CallbackFunction cb = CallbackFunction(printf, "Hello World!\n");

cb.call();

据我所知,这样做有 2 个问题:

1- 你不能存储目标...参数。编译器说 data member type contains unexpanded parameter pack 'targs'

2- 您不能按原样将参数发送到函数。你需要以某种方式解压它。编译器说 expression contains unexpanded parameter pack 'args'

做这样的事情的正确方法是什么?

最佳答案

template<class T>
using CallbackFunction=std::function<T()>;

CallbackFunction<void> cb = []{printf("Hello World!\n");};

cb();

类型T必须是类型的一部分,因此除非 C++17,否则您必须至少列出它。

targs...只是一个内部细节。 std::function对签名进行类型删除并且可以处理存储任何一组 targs...或其他状态。

一个可以调用的对象,返回T ,并存储一些状态,是一个 std::function<T()> .剩下的都是糟粕。

如果你真的需要

template <typename T>
class CallbackFunction {
  std::function<T()> fun;

public:
  template<class...targs>
  CallbackFunction(std::function<T(targs...)> fun, targs... args) : fun([=]{ return fun(args...); }){}
  T call() const {
    return fun();
  }
};

用移动语义优化它需要更多的工作。查找 std::apply 的实现:

  template<class...targs>
  CallbackFunction(std::function<T(targs...)> fun, targs... args) : fun(
    [fun=std::move(fun), args=std::make_tuple(std::move(args)...)]()->decltype(auto){
      return std::apply(fun,args);
    }
  ){}

关于c++ - 将回调函数打包到模板类中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45023506/

相关文章:

C++ 忽略某些输出的 cout 重定向

c++ - 乘以定义的符号: mysqlclient, pthread-win32

c++ - C++ 中的 vector : Why i'm getting so much errors for this simple copy & print program?

c++ - std::is_convertible 模板实现

c++ - 虚函数和 std::function?

c++ - 模板嵌套私有(private)类作为 friend

python - 如何识别 Bootstrap 模板中的 CSS 样式路径?

c++ - C 中的指针运算和 const 限定符

c++ - 如何在 C++ [库模式] 中抑制 LibSVM 的输出

c++ - C++中模板类的继承