可调用对象包装器

[TOC]

可调用对象包装器

可调用对象

可以按照函数的方法进行调用

分类

  • 函数指针

    使用using进行定义函数指针

    1
    using callBack = void(*)(int, double);
  • 仿函数

  • 可以转换为函数的类对象

  • 类成员的函数指针

  • 实例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    /*这段代码定义了一个名为name1的类,其中包含两个函数testFunc和testFunc2。testFunc是静态函数,可以通过指针调用,而testFunc2是实例方法,只能通过对象调用。

    此外,代码还定义了一个名为callBack的函数指针类型,它接受一个int类型和一个double类型的参数,并且没有返回值。在类定义中,将operator callBack()定义为转换运算符,它返回testFunc的指针,使得对象也可以像函数一样被调用。

    在main函数中,首先使用obj.operator callBack()将obj对象转换为callBack类型的函数指针,并将其赋值给func。然后,使用&name1::testFunc将testFunc的地址赋值给func2,使用&name1::testFunc2将testFunc2的地址赋值给func3。最后,使用func(1,2)调用testFunc函数。

    整体来说,此代码演示了如何定义和使用函数指针以及转换运算符的概念。*/

    #include<iostream>
    using namespace std;
    using callBack=void(*)(int ,double);
    class name1 {
    public:
    //callBack是定义的函数指针变量名,这一步是想将类名当作函数使用
    operator callBack (){
    return testFunc;
    }
    static void testFunc(int a,double b){
    cout<<a+b<<endl;
    }
    void testFunc2(int a,double b){
    cout<<a+b<<endl;
    }
    };



    int main()
    {
    using callBack2=void(name1::*)(int ,double);
    name1 obj;
    //通过转换运算符
    callBack func=obj.operator callBack();
    //通过函数指针
    callBack func2=&name1::testFunc;
    //callBack2是限定了作用域的函数指针,注意此处必须要有&
    callBack2 func3=&name1::testFunc2;

    func(1,2);
    return 0;
    }

function的使用

  • 作用:说是可调用对象当作函数使用

  • 使用示例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
      #include "iostream"
    #include "functional"
    #include"string"
    using callBack = void(*)(int a,std::string s);

    void func(int a,std::string s){
    std::cout<<"this is func"<<std::endl;
    std::cout<<"a = "<<a<<" string: "<<s<<std::endl;
    }

    struct testStruct{
    inline void operator()(int a,std::string s){
    std::cout<<"this is testStruct"<<std::endl;
    std::cout<<"a = "<<a<<" string: "<<s<<std::endl;
    }
    };

    class name1 {
    public:
    static void classFunc(int a,std::string s){
    std::cout<<"this is classFunc"<<std::endl;
    std::cout<<"a = "<<a<<" string: "<<s<<std::endl;
    }
    operator callBack (){
    return classFunc;
    }

    void operator()(int a,std::string s){
    std::cout<<"this is classOperator()"<<std::endl;
    std::cout<<"a = "<<a<<" string: "<<s<<std::endl;
    }
    };

    class print{
    public:
    print(const std::function<void(int,std::string)>& function1):tem(function1){};
    //调用function
    void Printf(int a,std::string s){
    tem(a,s);
    }
    private:
    std::function<void(int,std::string)> tem;
    };


    int main()
    {
    //通过函数包装器调用普通函数
    std::function<void(int,std::string)> f1=func;
    func(1,"chg");
    //伪函数
    std::function<void(int,std::string)> f2=testStruct();
    f2(2,"zjy");
    //类里面的静态函数
    f2=name1::classFunc;
    f2(3,"tsy");
    //通过转换运算符,将类变成了可调用对象
    name1 name;
    f2=name;
    f2(4,"xxp");

    //尝试将function当成参数,调用
    print objPrint(f1);
    objPrint.Printf(5,"jc");
    //因为我们的类是可调用的对象所以可以当作function
    print objPrint2(name);
    objPrint2.Printf(6,"wr");
    //调用类的静态
    print objPrint3(name.classFunc);
    objPrint3.Printf(7,"01");
    //普通函数调用
    print objPrint4(func);
    objPrint4.Printf(8,"gzx");
    //使用伪函数时需要创建对象
    testStruct testStruct;
    print objPrint5(testStruct);
    objPrint5.Printf(9,"tcx");

    return 0;
    }

    ## 可调用对象绑定器

    - 作用:
    - 将可调用对象绑定成仿函数
    - 将多元参数函数绑定成参数为1,或者(n-1)的可调用对象

    - 绑定非类的实例:

    ```c++
    #include "iostream"
    #include "functional"
    #include"string"

    void print(int a,std::string s){
    std::cout<<" a = "<<a<<" s = "<<s<<std::endl;
    }
    int main(){
    auto f1 = std::bind(print,std::placeholders::_1,std::placeholders::_2);
    f1(1,"chg");
    //注意如果在bind的时候初始化了a和s则在f2(),的括号中添加的参数,没有效果
    auto f2= std::bind(print,2,"zjy");
    f2();
    f2(3,"xxp");//无效果
    auto f3= std::bind(print,std::placeholders::_1,"xxp");
    f3(3);

    return 0;
    }
  • 绑定类里的成员函数和成员变量的实例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    #include "iostream"
    #include "functional"
    #include"string"

    class myClass {
    public:
    void test(int a,std::string s){
    std::cout<<"this is classFunc"<<std::endl;
    std::cout<<"a = "<<a<<" string: "<<s<<std::endl;
    }
    std::string s;
    };

    class print{
    public:
    print(const std::function<void(int,std::string)>& function1):tem(function1){};
    //调用function
    void Printf(int a,std::string s){
    tem(a,s);
    }
    private:
    std::function<void(int,std::string)> tem;
    };


    int main()
    {
    //类的成员函数的绑定
    myClass myclassObj1;
    auto f1= std::bind(&myClass::test,&myclassObj1,std::placeholders::_1,std::placeholders::_2);
    print frintObj1(f1);
    frintObj1.Printf(1,"chg");
    //绑定类的成员变量
    auto f2= std::bind(&myClass::s,&myclassObj1);
    f2()="chg";//对类成员赋值
    std::cout<<f2()<<std::endl;
    return 0;
    }

可调用对象包装器
https://tsy244.github.io/2023/03/26/cpp/可调用对象包装器/
Author
August Rosenberg
Posted on
March 26, 2023
Licensed under