Я работаю над библиотекой, основанной на простом событийно-система.
Для работы с элементами GUI («control») они очень нужны. Например, Window
класс имеет множество событий, таких как «onMouseMove», «onKeyPress», «onKeyRelease», .. Однако базовый класс для элементов управления — это Control
учебный класс. Он имеет виртуальную функцию draw (которая, очевидно, рисует элемент управления) и виртуальную функцию connect, которая связывает события элемента управления и главного окна (работает аналогично Qt Signal-Slot-Concept).
Но так как Event
класс занимает std::function<...>
указатель как субъект (=> слот), я не могу просто соединить функцию-член производного класса управления с событием окна. В качестве обходного пути я делаю следующее:
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(...);
}
};
Что это в основном делает, так это то, что он назначает лямбда-функцию std::function<...>
в конструкторе и придает, что std::function<...>
на выбранное событие.
Однако существует серьезная проблема: что произойдет, если я создам еще несколько объектов этого класса? Если бы у меня были обработчики событий, указанные в классе, как обычная функция, например:
void eventHandler() {
if ( someCondition ) this->onSomeCondition.notify();
}
И может назначить эту функцию std::function<...>
с помощью std::bind
, который не работает по какой-то причине, по крайней мере, пока я использую следующий вызов:
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::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);
Других решений пока нет …