sto*_*tic 4 c++ enums templates c++11
这是我试图编写的代码的简化版本:
template<typename Derived>
class StateMachine
{
public:
void SetState(Derived::State s) {
static_cast<Derived*>(this)->TransitionTo(s);
}
};
class MyFSM : public StateMachine<MyFSM>
{
public:
enum class State {
State1,
State2,
State3
};
void TransitionTo(State s) {
_state = s;
}
private:
State _state = State::State1;
};
Run Code Online (Sandbox Code Playgroud)
我正在使用带有clang的c ++ 11.我在这里得到的错误是10:17: error: missing 'typename' prior to dependent type name 'Derived::State'声明SetState.我也试过添加typename Derived::State DerivedState;然后使用DerivedState而不是Derived::State,但后来我得到了error: unknown type name 'DerivedState'.
更令人困惑的是,我试过typedef typename Derived::State DerivedState;,然后我得到了错误:error: no type named 'State' in 'MyFSM'.我的最后一次尝试是typedef enum class Derived::State DerivedState;,然后我得到了最令人困惑的错误:error: no enum named 'State' in 'MyFSM'.
我在这里深入了解模板,欢迎任何帮助理解这一点!此外,这里可能有更好的模式.我要做的主要是这个StateMachine类有一些共同的功能,然后有一堆不同的状态机,每个状态机都有自己的状态和转换功能.我这样做,需要传递的另一种方式this来SetState(从内调用时MyFSM,这是我在做什么的简化版本),但是这是丑陋的人,它自己的原因.我很想避免这种有层次性的课程,但我的主要目标是使派生类尽可能易于编写和理解.
小智 5
您可以通过制作SetState模板来延迟类型扣除:
#include <type_traits>
template<typename Derived>
class StateMachine
{
public:
template <typename State>
void SetState(State s) {
static_assert(std::is_same<State, typename Derived::State>::value, "Not a derived state");
static_cast<Derived*>(this)->TransitionTo(s);
}
};
class MyFSM : public StateMachine<MyFSM>
{
public:
enum class State {
State1,
State2,
State3
};
void TransitionTo(State s) {
_state = s;
}
private:
State _state = State::State1;
};
int main() {
MyFSM fsm;
fsm.SetState(MyFSM::State::State1);
// error: static assertion failed: Not a derived state
// fsm.SetState(0);
}
Run Code Online (Sandbox Code Playgroud)