简体   繁体   English

调用从另一个类传递过来的回调

[英]Calling a callback passed from another class

I want to register a callback handler (method) of the one class (Y) in another (X).我想在另一个(X)中注册一个类(Y)的回调处理程序(方法)。 I can't use std::function because of possible heap allocation and I must have an access to members of a class that registers the handler.由于可能的堆分配,我无法使用 std::function 并且我必须有权访问注册处理程序的类的成员。 I also want to avoid static functions.我也想避免静态函数。 I've came up with some workaournd but got stuck on calling the callback:我想出了一些workaournd,但在调用回调时卡住了:

template<class T>
using clbkType = void(T::*)(void);

template<class T>
class X
{
public:

    void registerClbck(clbkType<T> clbk) {
        callback = clbk;
    }

    void call() {
        callback(); // ERROR C2064: term does not evaluate to a function taking 0 arguments.
        //(((X<T>*)this)->X<T>::callback)(); // same error

    }
private:
    clbkType<T> callback;
};

class Y
{
public:

    Y() {
        x.registerClbck(&Y::handler);
    }

    // just for a test: fire a callback in class X
    void fire() {
        x.call();
    }

    int getA() { return a; }
private:
    int a{ 0 };
    X<Y> x{};

    void handler() {
        a = 5;
    }
};

int main()
{
    Y y;
    y.fire();
    return y.getA();
}

link to code: https://godbolt.org/z/PhY41xsWE代码链接: https : //godbolt.org/z/PhY41xsWE

PS.附注。 I'm not sure if this is a safe solution, so please put any comment on that.我不确定这是否是一个安全的解决方案,所以请对此发表任何评论。

Thanks!谢谢!

The member function pointer needs a specific class object to invoke, so you need to do this:成员函数指针需要一个特定的类对象来调用,所以你需要这样做:

template<class T>
class X
{
public:
    // ...
    void call(T& obj) {
      (obj.*callback)();
    }
    // ...
};

class Y
{
public:
    // just for a test: fire a callback in class X
    void fire() {
      x.call(*this);
    }
    // ...  
};

Demo.演示。

The member function pointer need an instance to be called on.成员函数指针需要一个实例来调用。

If you want to bind the instance, here is a possible way to implement it.如果你想绑定实例,这里是一种可能的实现方式。

template<typename T>
struct member_callback {
    T* instance;
    void(T::*callback)();
    void operator()(){(instance->*callback)();}
};

template<typename T>
struct X{
    void registerClbck(member_callback<T> clbk) { callback = clbk; }
    void call() { callback(); }
    member_callback<T> callback;
};

struct Y{
public:
    Y() { x.registerClbck({this,&Y::handler}); }
    void fire() { x.call(); }
    int getA() { return a; }
private:
    int a{ 0 };
    X<Y> x{};
    void handler(){ a = 5; }
};

int main()
{
    Y y;
    y.fire();
    return y.getA();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM