美文网首页
可调用对象

可调用对象

作者: arkliu | 来源:发表于2022-11-11 10:03 被阅读0次

    可调用对象分类

    • 函数指针
    void fun(int age, string name) {
        cout << "age :"<<age <<"   name:"<<name<<endl;
    }
    
    using funptr = void(*)(int,string);
    
    • 具有operator()成员函数的类对象(防函数)
    class AA{
        public:
            void operator()(string name) {
                cout << "AA name:" << name << endl;
            }
    };    
    
    int main() {
        AA a;
        a("hello world");
        return 0;
    }
    
    • lambda函数
    auto func1 = [](int age, string name) { 
            std::cout << age <<"  "<< name<<std::endl; 
        };
    func1(22, "张三");
    
    • 一个可被转换为函数指针的类对象
    void fun(int age, string name) {
        cout << "age :"<<age <<"   name:"<<name<<endl;
    }
    
    using funptr = void(*)(int,string);
    
    class AA{
        public:
            void operator()(string name) {
                cout << "AA name:" << name << endl;
            }
    
            operator funptr() {
                return printAA; // printAA这里必须是static类型
            }
    
            static void printAA(int age, string name) {
                cout << "age :"<<age <<"   name:"<<name<<endl;
            }
    };    
    
    int main() {
        AA a;
        a("hello world");
    
        AA aa;
        aa(33, "张三");
        return 0;
    }
    
    image.png
    • 类函数成员指针或类成员指针
    #include<iostream>
    #include<string>
    #include<typeinfo>
    #include <map>
    #include <vector>
    using namespace std;
    
    void fun(int age, string name) {
        cout << "age :"<<age <<"   name:"<<name<<endl;
    }
    
    using funptr = void(*)(int,string);
    
    class AA{
        public:
            int m_age;
            string m_name;
            void operator()(string name) {
                cout << "AA name:" << name << endl;
            }
            // 将类对象转换为函数
            operator funptr() {
                return printAA; // printAA这里必须是static类型
            }
    
            static void printAA(int age, string name) {
                cout << "printAA age :"<<age <<"   name:"<<name<<endl;
            }
    
            void fun1(int age ,string name) {
                cout << "fun1 age :"<<age <<"   name:"<<name<<endl;
            }
    };    
    
    int main() {
        // 类的函数指针
        funptr ptr1 = AA::printAA;
        using Fptr = void(AA::*)(int age, string name);
        Fptr ptr2 = &AA::fun1;
    
        AA aa;
        (aa.*ptr2)(33, "李四"); // fun1 age :33   name:李四
    
        // 类的成员指针
        using FMemberPtr = int AA::*;
        FMemberPtr ptr3 = &AA::m_age;
        aa.m_age = 45;
        cout << "aa.m_age = "<<aa.m_age<< endl; // aa.m_age = 45
        return 0;
    }
    

    可调用对象包装器

    std::function是可调用对象的包装器,它是一个类模板,可以容纳除了类成员(函数)指针之外的所有可调用对象,
    std::function 必须要包含一个叫做 functional 的头文件
    语法如下:

    #include <functional>
    std::function<返回值类型(参数列表)> name= 可调用对象;
    
    #include<iostream>
    #include<string>
    #include<typeinfo>
    #include <map>
    #include <vector>
    #include<functional>
    using namespace std;
    
    void fun(int age, string name) {
        cout << "age :"<<age <<"   name:"<<name<<endl;
    }
    
    using funptr = void(*)(int,string);
    
    class AA{
        public:
            int m_age;
            string m_name;
            void operator()(string name) {
                cout << "AA name:" << name << endl;
            }
    
            operator funptr() {
                return printAA; // printAA这里必须是static类型
            }
    
            static void printAA(int age, string name) {
                cout << "printAA age :"<<age <<"   name:"<<name<<endl;
            }
    
            void fun1(int age ,string name) {
                cout << "fun1 age :"<<age <<"   name:"<<name<<endl;
            }
    };    
    
    int main() {
        // 1. 包装普通函数
        function<void(int,string)>pfun1 = fun;
        // 2. 包装类的静态函数
        function<void(int,string)>pfun2 = AA::printAA;
        // 3. 包装仿函数
        AA a1;
        function<void(string)>pfun3 = a1;
        // 包装转换为函数指针的对象
        AA a2;
        function<void(int,string)>pfun4 = a2;
    
        // 包装lambda
        auto lamFun = [](int age, string name) { 
            std::cout << age <<"  "<< name<<std::endl; 
        };
        function<void(int,string)> pfun5 = lamFun;
        
        // 包装类的成员函数
        function<void(AA&, int,string)> pfun6 = &AA::fun1;
        
        //调用
        pfun1(11, "aaa");
        pfun2(22, "bbbb");
        pfun3("cccc");
        pfun4(33, "dddddd");
        pfun5(43, "sdfsdf");
        pfun6(a1, 66, "mmmm");
        return 0;
    }
    
    image.png

    std::bind

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

    std::bind语法

    // 绑定非类成员函数/变量
    auto f = std::bind(可调用对象地址, 绑定的参数);
    // 绑定类成员函/变量
    auto f = std::bind(类函数/成员地址, 类实例对象地址, 绑定的参数);
    
    

    bind基本用法

    void fun(int age, string name) {
        cout << "age :"<<age <<"   name:"<<name<<endl;
    }
    int main() {
        function<void(int,string)> fun_bind1 = bind(fun, placeholders::_1, placeholders::_2);
        fun_bind1(12, "王五");
    
        // 使用bind绑定参数顺序
        function<void(string,int)> fun_bind2 = bind(fun, placeholders::_2, placeholders::_1);
        fun_bind2("王五", 12);
    
        // 使用bind提前绑定参数, 默认bind绑定参数是值传递,如果要传递引用使用std::ref()处理
        int age = 18;
        // function<void(string)> fun_bind3 = bind(fun, age, placeholders::_1);
        function<void(string)> fun_bind3 = bind(fun, std::ref(age), placeholders::_1);
        age = 30;
        fun_bind3("牛牛牛牛牛");
    
        // function包装函数参数比bind绑定的函数参数个数多的情况
        function<void(int, string, int)> fun_bind4 = bind(fun, placeholders::_1, placeholders::_2);
        fun_bind4(22, "uuuu", 0);
        return 0;
    }
    
    image.png

    bind绑定

    int main() {
        // 1. 包装普通函数
        auto pfun1 = bind(fun, placeholders::_1, placeholders::_2);
        // 2. 包装类的静态函数
        auto pfun2 = bind(AA::printAA, placeholders::_1, placeholders::_2);
        // 3. 包装仿函数
        AA a1;
        auto pfun3 = bind(a1, placeholders::_1);
        // 包装转换为函数指针的对象
        AA a2;
        function<void(int,string)>pfun4 = bind(a2, placeholders::_1, placeholders::_2);
    
        // 包装lambda
        auto lamFun = [](int age, string name) { 
            std::cout << age <<"  "<< name<<std::endl; 
        };
        function<void(int,string)> pfun5 = bind(lamFun, placeholders::_1, placeholders::_2);
        
        // 包装类的成员函数, 使用bind直接绑定对象
        function<void(int,string)> pfun6 = bind(&AA::fun1, &a1, placeholders::_1, placeholders::_2);
        
        //调用
        pfun1(11, "aaa");
        pfun2(22, "bbbb");
        pfun3("cccc");
        pfun4(33, "dddddd");
        pfun5(43, "sdfsdf");
        pfun6(66, "mmmm"); // 上面使用bind直接绑定对象,这里使用时候,就不用传递对象了
        return 0;
    }
    
    image.png

    相关文章

      网友评论

          本文标题:可调用对象

          本文链接:https://www.haomeiwen.com/subject/pspazrtx.html