[英]statemachine using variadic template overloading
我正在嘗試使用可變參數模板在 C++ 中構建狀態機。
class Event {};
template<typename... TEvents>
class StateMachineActionHandler
{
public:
void action() = delete;
};
template<typename TEvent, typename... TEventRest>
class StateMachineActionHandler<TEvent, TEventRest...> : public StateMachineActionHandler<TEventRest...>
{
public:
virtual void action(const TEvent& event)
{
std::cout << "default" << std::endl;
}
using StateMachineActionHandler<TEventRest...>::action;
};
template <class ...TEvents>
class State : public StateMachineActionHandler<TEvents...>
{
public:
virtual void enterAction() = 0;
virtual void exitAction() = 0;
};
template <class ...TStates>
class StateMachine
{
public:
StateMachine()
{
m_cur = std::get<0>(m_states);
std::visit([](auto state){state.enterAction();}, m_cur);
}
virtual ~StateMachine() = default;
template<typename TEvent>
void handleEvent(const TEvent& event)
{
std::visit([&event] (auto state){ state.action(event);}, m_cur);
}
private:
std::tuple<TStates...> m_states;
std::variant<TStates...> m_cur;
};
然后我創建了一個實現此狀態機的 class。 但是對於StateA
,我不會覆蓋 function void action(const EventB& event)
,因為我希望它具有模板中提供的空默認實現。
class EventA : public Event {};
class EventB : public Event {};
class StateA : public State<EventA, EventB>
{
public:
void action(const EventA& event) override { std::cout << "new A A" << std::endl;}
void enterAction() override {std::cout << "enter A" << std::endl; }
void exitAction() override {std::cout << "exit A" << std::endl; }
};
class StateB : public State<EventA, EventB>
{
public:
void action(const EventA& event) override { std::cout << "new B A" << std::endl;}
void action(const EventB& event) override { std::cout << "new B B" << std::endl;}
void enterAction() override {std::cout << "enter B" << std::endl; }
void exitAction() override {std::cout << "exit B" << std::endl; }
};
class StateC : public State<EventA, EventB>
{
public:
void action(const EventA& event) override { std::cout << "new C A" << std::endl;}
void action(const EventB& event) override { std::cout << "new C B" << std::endl;}
void enterAction() override {std::cout << "enter C" << std::endl; }
void exitAction() override {std::cout << "exit C" << std::endl; }
};
class StateMachineTest : public StateMachine<StateA, StateB, StateC>
{
};
現在如果我使用這個 class 我得到一個編譯錯誤:
int main()
{
StateMachineTest testSM;
EventB eventB;
testSM.handleEvent(eventB);
}
error: cannot convert 'const EventB' to 'const EventA&'
為什么它看不到空的默認實現?
您需要使用using
-declaration 將默認實現引入派生的 class 定義
class StateA : public State<EventA, EventB>
{
public:
using State<EventA, EventB>::action;
void action(const EventA& event) override { std::cout << "new A A" << std::endl;}
void enterAction() override {std::cout << "enter A" << std::endl; }
void exitAction() override {std::cout << "exit A" << std::endl; }
};
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.