将成员函数和lambdas传递给std ::功能



我正在尝试创建控制/窗口事件,类似于在C#的Windows表单/WPF中完成的方式。每个事件类都包含一个参数类型,并传递该类型以及指向发送对象的指针。使用lambda函数时,这一切都很好,但是当我尝试在事件中添加成员函数时,我会收到C2276 '&': illegal operation on bound member function expressionC2660 'Event<MouseButtonEventArgs>::add': function does not take 1 arguments的编译错误。

我将如何创建一个可以从任何类中获取lambda函数和成员功能的事件类(无论该类是"发送者")?

event.h

template<class Args> struct EventListener {
    /* The function type to be called by the event. */
    typedef function<void(ControlBaseSPtr, Args&)> ArgsFunction;
    string name;
    ArgsFunction function;
};
template<class Args> class Event {
    /* The function type to be called by the event. */
    typedef function<void(ControlBaseSPtr, Args&)> ArgsFunction;
    deque<EventListener<Args>> listeners;
    Event(EventDirections direction) {
        this->direction = direction;
    }
    void add(const string& name, ArgsFunction function) {
        EventListener<Args> listener = EventListener<Args>(name, function);
        for (auto it = listeners.begin(); it != listeners.end(); it++) {
            if (it->name == name) {
                throw exception("Event::operator+= listener already exists in the event");
            }
        }
        listeners.push_back(listener);
    }
    //...
};

control.h

class ControlBase {
    Event<MouseEventArgs> _eventMouseMovedGlobal;
    Event<MouseButtonEventArgs> _eventMouseButtonGlobal;
    ControlBase();
    void onMouseMovedGlobal(ControlBaseSPtr sender, MouseEventArgs e);
};

control.cpp

ControlBase::ControlBase() {
    // Works
    _eventMouseButtonGlobal.add("some name", [](ControlSPtr control, MouseButtonEventArgs e){
        //...
    };
    // Doesn't work
    _eventMouseMovedGlobal.add("some name", bind(&onMouseMovedGlobal, this, placeholders::_2))
    // Doesn't work
    _eventMouseMovedGlobal.add("some name", bind(&onMouseMovedGlobal, this))
}
void ControlBase::onMouseWheelGlobal(ControlBaseSPtr sender, MouseWheelEventArgs e) {
    //...
}

好吧,由于onMouseMovedGlobal有2个输入参数,因此在创建粘合剂时,您都需要占位符或值。因此,而不是

_eventMouseMovedGlobal.add("some name", bind(&onMouseMovedGlobal, this, placeholders::_2))

您需要

_eventMouseMovedGlobal.add("some name", bind(&ControlBase::onMouseMovedGlobal, this, placeholders::_1, placeholders::_2))

最新更新