可调用对象

2022-11-11  本文已影响0人  arkliu

可调用对象分类

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;
        }
};    

int main() {
    AA a;
    a("hello world");
    return 0;
}
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
上一篇 下一篇

猜你喜欢

热点阅读