使用 std::variant<...时调用 BaseState 函数而不是派生函数>



我正在试验 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 enterrn");};
void on_event (const Reset &r);
};
struct LightOn : BaseState
{
LightOn(){Serial.printf("LightOn constructorrn");};
void on_event(const Event &e);
void on_exit(){Serial.printf("LightOn exitrn");}
void on_enter(){Serial.printf("LightOn enterrn");}
};
struct LightOff : BaseState
{
LightOff(){Serial.printf("LightOff constructorrn");};
void on_event(const Event &e);
void on_exit(){Serial.printf("LightOff exitrn");}
};
struct Toggle
{
Toggle(){Serial.printf("Struct Togglern");};
};
struct Reset
{
Reset(){Serial.printf("Struct Resetrn");};
};
void LightOn::on_event(const Event &e){Serial.printf("LightOn eventrn");};
void LightOff::on_event(const Event &e){Serial.printf("LightOff eventrn");};
void BaseState::on_event(const Reset &r){Serial.printf("BaseState resetrn");};

我的问题是在on_event函数中。

在巴斯庄园void on_event(const Reset &r);中有一个关于重置的特定 在 LightOn 和 LightOffvoid on_event(const Event &e);中有一个更通用的(使用 Event = std::variant<切换,重置>;)

但是当我这样做时

LightOn n;
n.on_event(Reset{}); 

来自LightOn的on_event被调用,而不是来自BaseState的。

有没有办法实现:当一个基态函数可用于这个特定事件时调用基态函数?

这个问题也回答了类似的事情。

名称查找在子类处停止(因为那里有匹配项(。

您可以使用using将基类(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 enterrn");};
void on_event (const Reset &r);
};
struct LightOn : public BaseState
{
LightOn(){Serial.printf("LightOn constructorrn");};
using BaseState::on_event; // <-- Added to the scope
void on_event(const Event &e); 
void on_exit(){Serial.printf("LightOn exitrn");}
void on_enter(){Serial.printf("LightOn enterrn");}
};
struct LightOff : public BaseState
{
LightOff(){Serial.printf("LightOff constructorrn");};
void on_event(const Event &e);
void on_exit(){Serial.printf("LightOff exitrn");}
};
struct Toggle
{
Toggle(){Serial.printf("Struct Togglern");};
};
struct Reset
{
Reset(){Serial.printf("Struct Resetrn");};
};
void LightOn::on_event(const Event &e){Serial.printf("LightOn eventrn");};
void LightOff::on_event(const Event &e){Serial.printf("LightOff eventrn");};
void BaseState::on_event(const Reset &r){Serial.printf("BaseState resetrn");};

另外,请查看 Boost 编译时 FSM 生成器示例。它似乎实现了与您相同的目标。

最新更新