实现任意函数调用的代码

参考:https://www.jianshu.com/p/f191e88dcc80

1. std::function

  • std::function 是一个可调用对象包装器,是一个类模板,可以容纳除了类成员函数指针之外的所有可调用对象,它可以使用统一的方式处理函数、函数对象、函数指针,并允许保存和延迟它们的执行。
  • 定义格式:std::function<函数模板> 
  • std::function 可以取代函数指针的使用,因为它可以延迟函数的执行,特别适合作为回调函数使用。它比普通函数指针更加的灵活和便利。

2. std::bind

     可将std::bind函数看作一个通用的函数适配器,它接受一个可调用对象,生成一个新的可调用对象来“适应”原对象的参数列表。

std::bind将可调用对象与其参数一起进行绑定,绑定后的结果可以使用std::function保存。

std::bind主要有以下两个作用:

  • 将可调用对象和其参数绑定成一个防函数(防函数是啥需要再查查资料,哈哈)
  • 只绑定部分参数,减少可调用对象传入的参数

下面是利用std::function, std::bind以及带参模板函数,实现的一段代码,这段代码可以保存任意“可调用对象”,并保存和延迟了他们的执行。非常适合用来作为各类回调函数的抽象接口。

include<functional> // std::function
#include<utility> // std::forward 

class CallBack{
    public:
        template<class F, class... Args>
            CallBack(F&& f, Args&&... args){
                task = std::bind(std::forward<F>(f), std::forward<Args>(args)...); // std::forward 完美转发,实现了参数在传递过程中保持其值属性的功能,即若是左值,则传递之后
            }                                                                   // 仍是左值,若是右值,则传递之后仍是右值。

        void Run(){
            task();
        }

        virtual ~CallBack(){}

    private:
        std::function<void()> task; // std::function 一种通用的多态函数包装器, std::function的实例可以存储、复制和调用任何可调用的目标(函数、lamda表达式、绑定表达式或其他函数对象,以及指>向成员函数的指针和指向数据成员的指针)
};

template<class F, class... Args>
CallBack* NewCallBack(F&& f, Args&&... args){
    return new CallBack(f, args...);
}


class sample{
public:
  void func2(int a, int b){
   a_ = a;
   b_ = b;
   printf("a=%d, b=%d
", a_, b_);
  }

  void run(){
   CallBack * cb2 =   NewCallBack(&sample::func2, this, 200, 300); // 在类内部,传入成员函数时,需要传入this指针
   cb2->Run();
  }

  private:
   int a_;
   int b_;
};


void func(){
    printf("hello
");
}

void func1(int a){
    printf("hello, %d
", a);
}

int main(){

    CallBack * cb =   NewCallBack(func);
    CallBack * cb1 =   NewCallBack(func1, 200);
    sample s;
//    CallBack * cb2 =   NewCallBack(&sample::func2, &s, 200, 300); // 在内外部调用成员函数,需要传入对象的引用
    cb->Run();
    cb1->Run();
//    cb2->Run();
    s.run();

    std::function<void()> f = std::bind(func1, 1); // 使用function<void()>和std::bind可以将各类函数统一成一个接口
// 运行时调用接口一样,非常易用于回调过程,简化了参数处理。 f();
return 0;

运行结果:

[daq@centos build]$ ./hello-exe/cmake-good 
hello
hello, 200
a=200, b=300
hello, 1

  

原文地址:https://www.cnblogs.com/zengtx/p/11912798.html