zoukankan      html  css  js  c++  java
  • 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);
    

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

  • 相关阅读:
    Eclipse (indigo) 中安装jdk包并执行Maven
    UVA
    Android 仿QQ界面的实现
    Ajax是什么
    jieba.NET与Lucene.Net的集成
    jieba中文分词的.NET版本:jieba.NET
    SharePoint 2013技巧分享系列
    SharePoint 2013常用开发工具分享
    SharePoint 2013技巧分享系列
    SharePoint 2013技巧分享系列
  • 原文地址:https://www.cnblogs.com/Stultz-Lee/p/10067540.html
Copyright © 2011-2022 走看看