[英]Trouble with a GUI toolkit in C++. Passing lambdas into a vector of std::function
我遇到的問題有點難以描述,但我會盡力使其易於理解。
我正在創建一個類似於 C# 中的 Windows 窗體系統的 C++ GUI 工具包。 整個系統是基於事件的。 我的Event
類由std::function
的向量組成,它充當訂閱者函數的列表和一些實用程序方法。
template<class T>
class Event
{
public:
Event() {}
~Event() {}
void Raise(T context)
{
for(std::function<void(T&)> subscriber : Subscribers)
{
subscriber(context);
}
}
void Subscribe(std::function<void(T&)> subscriber)
{
try { Subscribers.push_back(subscriber); } catch (std::exception) { /*...*/ }
}
private:
std::vector<std::function<void(T&)>>> Subscribers;
}
我的項目包含一個EventProvider
類,它為所有派生類提供一堆事件。
class EventProvider
{
public:
Event<LoadEventContext> LoadEvent;
// ...
// ...
}
也像在 Windows 窗體中一樣,我有一個Window
類和一個Control
類。 它們都繼承了EventProvider
。 與 C# 中一樣,定義所有功能的實際 Window 類必須繼承Window
類。
class Control : public EventProvider { /*...*/ }
class Window : public EventProvider { /*...*/ }
class MyWindow : public Window { /*...*/ }
在我的MyWindow
類中,我通過 lambda 將方法綁定到 Window 的事件。 綁定的方法MyWindow
類的事件MyWindow
類的工作就好了。 將控件的成員函數綁定到MyWindow
的事件也沒有問題。 在 Windows 窗體中,控件的所有事件方法也包含在 Window 類中。 我想在我的項目中做同樣的事情。 所以MyWindow
類包含我的控件的實例、它自己的事件方法和我的控件的事件方法。 但是,當我嘗試將控件事件函數綁定到控件事件時,出現運行時錯誤。
// === MyWindow.hpp ===
#ifndef __MY_WINDOW_HPP__
#define __MY_WINDOW_HPP__
#include <Control.hpp>
#include <Window.hpp>
class MyWindow : public Window
{
public:
MyWindow();
~MyWindow();
private:
Control* button = nullptr;
void OnLoadEvent(LoadEventContext& context);
void button_OnLoadEvent(LoadEventContext& context);
}
#endif
// === MyWindow.cpp ===
#include <MyWindow.hpp>
MyWindow::MyWindow()
{
button = new Control();
LoadEvent.Subscribe([&](LoadEventContext& context) { OnLoadEvent(context); }); // WORKS
LoadEvent.Subscribe([&](LoadEventContext& context) { button->OnLoadEvent(context); }); // WORKS
button->OnLoadEvent.Subscribe([&](LoadEventContext& context) { OnLoadEvent(context); }); // Runtime Error
}
MyWindow::~MyWindow() { /*...*/ }
MyWindow::OnLoadEvent(LoadEventContext& context) { /*...*/ }
MyWindow::button_OnLoadEvent(LoadEventContext& context) { /*...*/ }
//
當MyWindow
調用控件的加載事件以將 lambda 函數添加到訂閱者函數的事件向量時,會在 stl 的vector
類中引發讀取訪問沖突。
這行代碼調用了添加 lambda 函數的事件:
button->OnLoadEvent.Subscribe([&](LoadEventContext& context) { OnLoadEvent(context); }); // Runtime Error
而Event
類中的這個導致了錯誤:
try { Subscribers.push_back(subscriber); } catch (std::exception) { /*...*/ }
我在使用函數指針、函子、functionoids 和所有這些東西進行編程方面仍然不是很先進。 盡管如此,我希望我已經足夠清楚地為你指出了我的問題,我希望任何人都可以幫助我解決這個問題。
我懂了。 問題是我在完全創建此控件之前將我的事件方法綁定到我的控件的事件。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.