使用可变参数模板重载的状态机
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
,我没有覆盖函数 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
声明将默认实现引入派生的 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; }
};
我正在尝试使用可变参数模板在 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
,我没有覆盖函数 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
声明将默认实现引入派生的 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; }
};