【发布时间】:2020-06-14 00:33:25
【问题描述】:
完成此操作的正确语法是什么?这个想法是任何类的某些对象都可以在 GuiButton 类中存储 lambda 表达式,然后调用该 lambda 表达式并访问其自己的局部变量。
需要注意的是,我的平台(Arduino)不支持functional 标头。
我编写的代码试图表达这个想法(由于 lambda 表达式无法访问 ExampleScreen 的成员,因此无法编译):
struct GuiButton {
uint8_t x; //coordinates for displaying this GUI element
uint8_t y;
GuiButton(uint8_t _x, uint8_t _y, void (*_callback)()) :
x(_x),
y(_y),
callback(_callback)
{};
virtual void draw(bool _highlight);
public:
void (*callback)(); //to be executed BY THE PARENT OBJECT when this element is clicked
};
struct GuiTextButton: public GuiButton {
char* text; //text to display in this GUI element
GuiTextButton(uint8_t _x, uint8_t _y, char* _text, void (*_callback)()) :
GuiButton(_x, _y, _callback),
text(_text)
{};
void draw(bool _highlight);
};
class ExampleScreen{
private:
GuiButton** buttonPtr;
uint8_t buttonCount;
uint8_t selectedButton;
bool proc1Active;
bool proc2Active;
public:
ExampleScreen() :
buttonPtr(NULL),
buttonCount(0),
selectedButton(0),
proc1Active(false),
proc2Active(false)
{
//different derived classes of GuiScreen shall have different constructors to define
//their visual and functional elements
buttonPtr = new GuiButton* [2];
buttonCount = 2;
{
char text[] = "Button1";
GuiButton *_thisPtr = new GuiTextButton(5,0,text, []() {
proc1Active = ~proc1Active;
});
buttonPtr[0] = _thisPtr;
}
{
char text[] = "Button2";
GuiButton *_thisPtr = new GuiTextButton(5,0,text, []() {
proc2Active = ~proc2Active;
});
buttonPtr[2] = _thisPtr;
}
};
void click() {
void (*callback)() = (buttonPtr[selectedButton]->callback);
callback();
};
};
int main() {
ExampleScreen gui;
gui.click();
};
【问题讨论】:
-
您的 lambda 表达式需要捕获
this。但随后它们将无法转换为普通函数指针。所以,无论你在哪里使用void (*_callback)()或类似名称,都将其更改为std::function<void()> _callback -
我忘了提到我无法访问
functional标头。问题已更新,谢谢! -
那你根本不能这样做。不幸的是,C++ 不能以这种方式工作。
-
然后用老式的方式来做。让回调将
void*指针作为参数,其中可以传递上下文。让GuiButton获取并存储回调和上下文指针;调用回调时将后者传递给前者。在ExampleScreen中,将this作为上下文指针传递,让回调将其转换回ExampleScreen* -
我不能完全遵循这一点,但它确实看起来合理吗?你能把它更直接地拼出来作为答案吗?