代码之家  ›  专栏  ›  技术社区  ›  dsp_user

泛型成员函数指针

  •  2
  • dsp_user  · 技术社区  · 7 年前

    我想知道在标准C++中是否有一种方法(似乎不支持这种方法,但我可能没有仔细研究)来声明指向具有相同签名的任何类的成员函数的指针。例如,X和Y具有具有相同签名的echoX和echoY方法

    class X{
      int val;
    public:
     int echoX(int v)  {
     val = v;
     return v; }
       int getValue() const { return val; }
    };
    
    class Y{
    
       int val;
       public:
       int echoY(int v)  {
       val = v;
       return v;
       }
       int getValue() const { return val; }
    };
    

    一些C++实现通过扩展允许此功能(例如VCL使用 __closure 关键字)。

    typedef int (__closure *IntFunPtr)(int);
    

    现在,编写一个能够调用 X::echoX Y::echoY

    void CallObjectMethod(IntFunPtr fPtr, int val){
    
        fPtr(val);//this can call any member method that accepts an int and returns an int
    }
    
    
    X x, x1;
    CallObjectMethod(&x.echoX,4);
    CallObjectMethod(&x1.echoX,20);
    
    Y y, y1;
    CallObjectMethod(&y.echoY,10);
    CallObjectMethod(&y1.echoY,15);
    

    此功能对于实现事件处理程序非常有用。

    非常感谢。

    2 回复  |  直到 7 年前
        1
  •  3
  •   lars    7 年前

    例如,X和Y具有具有相同签名的echoX和echoY方法

    如果它们没有相同的签名,那么它们对类实例有一个隐式的第一个参数。通常你会选择 std::function 摆脱第一个论点。

    #include <functional>
    
    class X { public: int echoX(int v) {return v; } };
    
    class Y { public: int echoY(int v) {return v; } };
    
    typedef std::function<int(int)> IntFunction;
    
    int echo(IntFunction func, int v)
    {
        return func(v);
    }
    
    int main()
    {
        int v = 5;
        X x;
        Y y;
        int a = echo(std::bind(&X::echoX, x, std::placeholders::_1), v);
        int b = echo(std::bind(&Y::echoY, y, std::placeholders::_1), v);
    }
    
        2
  •  1
  •   Samer Tufail    7 年前

    您可以创建一个通用模板函数,该函数接受您感兴趣的签名,传入对象实例和指向成员函数的指针。例如:

    template<typename T>
    void CallObjectMethod(int(T::*func)(int), T& obj, int val)
    {
        cout << (obj.*func)(val);
    }
    

    现在,按照您在示例中提到的方式进行调用:

    X x, x1;
    CallObjectMethod(&X::echoX, x, 10);
    CallObjectMethod(&X::echoX, x1, 20);
    

    对于对象Y,可以执行以下操作:

    Y y, y1;
    CallObjectMethod(&Y::echoY, y, 10);
    CallObjectMethod(&Y::echoY, y1, 20);