我正在试验finate状态机和std::variant<..>;
std::variant将保存所有可能的状态,这些状态将在状态类中定义。
我想要的是有一个BaseState类,其中应该处理“泛型事件”。 派生状态类处理特定状态。
struct LightOn;
struct LightOff;
struct Toggle;
struct Reset;
using State = std::variant<LightOn,LightOff>;
using Event = std::variant<Toggle,Reset>;
struct BaseState
{
void on_enter(){Serial.printf("BaseState enter\r\n");};
void on_event (const Reset &r);
};
struct LightOn : BaseState
{
LightOn(){Serial.printf("LightOn constructor\r\n");};
void on_event(const Event &e);
void on_exit(){Serial.printf("LightOn exit\r\n");}
void on_enter(){Serial.printf("LightOn enter\r\n");}
};
struct LightOff : BaseState
{
LightOff(){Serial.printf("LightOff constructor\r\n");};
void on_event(const Event &e);
void on_exit(){Serial.printf("LightOff exit\r\n");}
};
struct Toggle
{
Toggle(){Serial.printf("Struct Toggle\r\n");};
};
struct Reset
{
Reset(){Serial.printf("Struct Reset\r\n");};
};
void LightOn::on_event(const Event &e){Serial.printf("LightOn event\r\n");};
void LightOff::on_event(const Event &e){Serial.printf("LightOff event\r\n");};
void BaseState::on_event(const Reset &r){Serial.printf("BaseState reset\r\n");};
我的问题在on_event
函数中。
在basestevoid on_event(const Reset&r);
中有一个关于Reset的特定选项,在LightOn和LightOffvoid on_event(const Event&e);
中有一个更通用的选项(使用Event=std::variant
但当我这么做的时候
LightOn n;
n.on_event(Reset{});
调用的是来自LightOn的on_event,而不是来自BaseState的on_event。
有没有一种方法可以实现:当BaseState函数可用于此特定事件时调用BaseState函数?
这个问题也回答了类似的问题。
名称查找在子类处停止(因为那里有一个匹配项)。
您可以使用using
将函数从基类(baseSteat
)引入到相同的作用域中。 (这将使它遵循通常的重载规则,在本例中选择精确的匹配项,即来自基类的函数。)
struct LightOn;
struct LightOff;
struct Toggle;
struct Reset;
using State = std::variant<LightOn,LightOff>;
using Event = std::variant<Toggle,Reset>;
struct BaseState
{
void on_enter(){Serial.printf("BaseState enter\r\n");};
void on_event (const Reset &r);
};
struct LightOn : public BaseState
{
LightOn(){Serial.printf("LightOn constructor\r\n");};
using BaseState::on_event; // <-- Added to the scope
void on_event(const Event &e);
void on_exit(){Serial.printf("LightOn exit\r\n");}
void on_enter(){Serial.printf("LightOn enter\r\n");}
};
struct LightOff : public BaseState
{
LightOff(){Serial.printf("LightOff constructor\r\n");};
void on_event(const Event &e);
void on_exit(){Serial.printf("LightOff exit\r\n");}
};
struct Toggle
{
Toggle(){Serial.printf("Struct Toggle\r\n");};
};
struct Reset
{
Reset(){Serial.printf("Struct Reset\r\n");};
};
void LightOn::on_event(const Event &e){Serial.printf("LightOn event\r\n");};
void LightOff::on_event(const Event &e){Serial.printf("LightOff event\r\n");};
void BaseState::on_event(const Reset &r){Serial.printf("BaseState reset\r\n");};
另外,看一看Boost编译时FSM生成器示例。 它似乎和你完成了同样的目标。