• 实现任意函数调用的代码


    参考: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

      

  • 相关阅读:
    ASP.NET MVC3 的一个OutputCache问题
    好用的服务器软件安装工具
    IO(五)----打印流
    HDU 5873 Football Games 【模拟】 (2016 ACM/ICPC Asia Regional Dalian Online)
    HDU 5874 Friends and Enemies 【构造】 (2016 ACM/ICPC Asia Regional Dalian Online)
    HDU 5876 Sparse Graph 【补图最短路 BFS】(2016 ACM/ICPC Asia Regional Dalian Online)
    makefile编写_简单
    3.6.3 不可变字符串
    使用VisualStudio进行脚本|样式文件压缩
    Java笔记--网络编程
  • 原文地址:https://www.cnblogs.com/zengtx/p/11912798.html
Copyright © 2020-2023  润新知