类内部的Std::bind,事件系统的一般概念

std::bind inside of a class, general concept of an event system

本文关键字:事件系统 bind 内部 Std      更新时间:2023-10-16

我正在开发一个基于简单事件系统的库。

对于GUI元素("控件")的工作,这些是非常需要的。例如,Window类有一堆事件,如"onMouseMove","onKeyPress","onKeyRelease",…但是,控件的基本类是Control类。它有一个虚拟函数draw(显然绘制控件)和一个虚拟函数connect连接控件和主窗口的事件(类似于Qt信号槽概念)。

但是由于Event类以std::function<...>指针作为主题(=> Slot),我不能简单地将派生控制类的成员函数与窗口的事件连接起来。作为一种解决方法,我正在做以下事情:

class A : public Control {
    friend class Window;
    public:
        A(){
            this->eventHandler = [this] () -> void {
                 if ( someCondition ) this->onSomeCondition.notify();
            };
        }
        Event<> onSomeCondition;
    protected:
        std::function<void()> eventHandler;
        void connect(Window *window){
            window->onSomeHigherEvent.attach(&this->eventHandler);
        }
        void draw(...) const{
            drawSome(...);
        }
};

这基本上是将一个lambda函数分配给构造函数中的std::function<...>,并将该std::function<...>附加到所选事件。

但是有一个主要的问题:如果我实例化该类的更多对象会发生什么?如果我在类中指定了事件处理程序,像这样的普通函数:
void eventHandler() {
    if ( someCondition ) this->onSomeCondition.notify();
}

并且可以使用std::bind将该函数分配给std::function<...>,这由于某种原因不起作用,至少只要我使用以下调用:

std::bind(&A::eventHandler, this, std::placeholders::_1); // *this will not work since that's just a (reference to the?) copy to of the object.

无论如何,lambda-function-workaround似乎时间效率较低,因为它并没有真正内置到类中。有没有更有效的方法来解决这个问题?也许不是通过解决函数问题而是通过改变概念?

我不知道你在问什么,因为我找不到问题,但是…

std::bind(&A::eventHandler, this, std::placeholders::_1); // *this will not work since that's just a (reference to the?) copy to of the object.

这创建了一个可调用的对象,它有一个未绑定的参数,也就是说,它期望被调用时只有一个参数,这与std::function<void()>不兼容,因为这是一个期望被调用时没有参数的函数。它也不兼容eventHandler成员函数,因为它也不带参数。

也许你只想使用std::bind(&A::eventHandler, this);