• C++可调用对象与函数表


    c++的可调用对象 有

    • 函数
    • 函数指针
    • lambda表达式
    • bind的对象
    • 重载了函数调用运算符的类

    如何调用?

    函数调用

    void afuncToCall()
    {
        cout << "call me"<<"
    ";
    }
    //1.call function
        afuncToCall();
    

    函数指针调用

    void func(int i){
        cout << "a function called by function pointer i= "<<i<<"
    ";
    }
    //声明一个函数指针
    void(*f)(int i);
    //对函数指针赋值
    f=func;
    //调用指针函数
    f(5);
    

    或者使用typedef缩写函数指针

    //function pointer
    typedef  void(*AbleCallFuncP)(int i) ;
    //2.function pointer
    AbleCallFuncP callFuncPointer= func;
    callFuncPointer(5);
    

    lambda表达式调用

    auto flambda = [](int i){
        cout << "lambda i is " << i << "
    ";
    };
    flambda(7);
    

    bind的对象

    #include <functional>
    void func(int i){
        cout << "a function called by bind object i= "<<i<<"
    ";
    }
    
    auto fbind = bind(func,std::placeholders::_1);
    fbind(9);
    

    重载了函数调用运算符的类

    struct callableStruct
    {
        int operator()(int val){
        	return (val<0)?-val:val;
        }
    };
    // callableStruct callableSut;
    int i = callableSut(-2);
    

    函数表

    现在,我们拥有了5种函数调用方式,那么,在一个项目里,我们很可能希望使用一个统一的函数表来管理这些函数调用对象,以上面的函数为例,我们其实拥有了5个参数为int类型的调用对象,使用map可以方便地实现函数表;

    只是,问题在于,这5种可调用对象的类型是不同的,我们无法将他们使用同一种类型放入map的second字段中,于是万能的C++标准大神们发明了function类模板来解决这个问题。

    罗列5种可调对象如下:

    //function
    void afuncToCall(int i)
    {
        cout << "call me a plain functon i is "<<i <<"
    ";
    }
    //function pointer
    typedef  void(*AbleCallFuncP)(int i) ;
    
    //called by function pointer
    void func1(int i){
        cout << "a function called by function pointer i= "<<i<<"
    ";
    }
    
    //called by bind
    void func2(int i){
        cout << "a function called by bind i= "<<i<<"
    ";
    }
    
    //callable class
    struct callableStruct
    {
        void  operator()(int i){
    	    cout << "a function called by callableStruct i= "<<i<<"
    ";
        }
    };
    
    //1.call function
    	//afuncToCall();
    // //2.function pointer
        AbleCallFuncP callFuncPointer= func1;
    //3.lambda 
        auto flambda = [](int i){
        	cout << "lambda i is " << i << "
    ";
        };
    //4 bind
        auto fbind = bind(func2,std::placeholders::_1);
    //5.operator ()
        callableStruct callableSut;
    

    让我们用function统一它们的类型

    #include <functional>
    #include <map>
    #include <string>
    // using std::map;
    void TestCallableObj()
    {
        typedef function<void(int)> FuncVI;
        typedef map<string,FuncVI> FuncAbleObjMap;
        FuncAbleObjMap callableObjMap;
    
        callableObjMap.insert(FuncAbleObjMap::value_type(string("plain function call"),afuncToCall));
        callableObjMap.insert(FuncAbleObjMap::value_type(string("function pointer call"),callFuncPointer));
        callableObjMap.insert(FuncAbleObjMap::value_type(string("lambda call"),flambda));
        callableObjMap.insert(FuncAbleObjMap::value_type(string("bind call"),fbind));
        callableObjMap.insert(FuncAbleObjMap::value_type(string("operator() call"),callableStruct()));
    
        callableObjMap["plain function call"](1);
        callableObjMap["function pointer call"](2);
        callableObjMap["lambda call"](3);
        callableObjMap["bind call"](4);
        callableObjMap["operator() call"](5);
    }
    

    输出结果

    call me a plain functon i is 1
    a function called by function pointer i= 2
    lambda i is 3
    a function called by bind i= 4
    a function called by callableStruct i= 5
    

    由此可见,通过function模板,我们将类型本不同的5个可调用对象打包成统一的类型,因为它们的返回值和参数类型是完全一样的。通过函数表的使用,我们可以写出封装更好的调用函数。

    如果觉得这样的调用太繁琐,可以使用宏来缩写下
    比如:

    #define CALL1(x)  callableObjMap[#x](1);
    CALL1(plain function call);
    CALL1(bind call);
    

    备注,本文没有涉及到函数成员函数 和静态成员函数的调用,权当归类到函数一类了。但是其调用细节和函数还是有差异的。

  • 相关阅读:
    hdu 4614 线段树 二分
    cf 1066d 思维 二分
    lca 最大生成树 逆向思维 2018 徐州赛区网络预赛j
    rmq学习
    hdu 5692 dfs序 线段树
    dfs序介绍
    poj 3321 dfs序 树状数组 前向星
    cf 1060d 思维贪心
    【PAT甲级】1126 Eulerian Path (25分)
    【PAT甲级】1125 Chain the Ropes (25分)
  • 原文地址:https://www.cnblogs.com/Stultz-Lee/p/10067540.html
Copyright © 2020-2023  润新知