我遇到以下代码的问题:
#include "tinyfsm.hpp"
struct Event : tinyfsm::Event { };
struct State1;
struct State2;
struct Fsm : tinyfsm::Fsm<Fsm> {
virtual void react(Event const &) { }
virtual void entry() { }
void exit() { };
virtual ~Fsm() { }
};
struct State1 : Fsm{
void react(Event const & event) override { transit<State2>(); }
void entry() override { }
};
struct State2 : Fsm{
void react(Event const & event) override { transit<State1>(); }
void entry() override { }
};
FSM_INITIAL_STATE(Fsm, State1)
编译器给出消息:
"..srctinyfsm.hpp", line 134: cc0513: error: a value of type "State2 *" cannot be assigned to an entity of type "Fsm *"
current_state_ptr = &_state_instance<S>::value;
^
detected during instantiation of "void tinyfsm::Fsm<F>::transit<S>() [with F=Fsm, S=State2]" at line 31 of "..srctestbed.cpp"
我确信这是因为编译器不理解State2继承自Fsm。
有没有什么方法可以打破循环依赖关系,或者向编译器提供相关信息,使其能够正确编译?
我使用的是ccblkfn.exe版本8.12.0.0(在blackfin处理器上工作(
我认为这可能是一个编译器错误,因为这段代码在g++6.3.0上编译得很好。
编译错误似乎是因为:
struct Fsm : tinyfsm::Fsm<Fsm>
这在全局命名空间中声明了一个名为Fsm
的struct
。
标头在tinyfsm
命名空间中定义了一个具有相同名称的类型。宏调用
FSM_INITIAL_STATE(Fsm, State1)
扩展到此宏声明:
#define FSM_INITIAL_STATE(_FSM, _STATE)
namespace tinyfsm {
template<> void Fsm< _FSM >::set_initial_state(void) {
current_state_ptr = &_state_instance< _STATE >::value;
}
}
这最终扩展到:
namespace tinyfsm {
template<> void Fsm<Fsm>::set_initial_state(void) {
current_state_ptr = &_state_instance< _STATE >::value;
}
}
你认为<Fsm>
部分最终指的是什么?不是您的类,而是tinyfsm命名空间中的Fsm
模板。Hillarity随之而来。
有几种简单的方法可以解决这种歧义。
FSM_INITIAL_STATE(::Fsm, State1)
宏现在在全局命名空间中插入对Fsm
结构的引用。
另一种方法是简单地将Fsm
类重命名为其他类。
第三种方法是将所有类放入它们自己的命名空间中,然后(在命名空间之外(。
namespace fsmimpl {
// Your existing class declarations
}
FSM_INITIAL_STATE(fsmimpl::Fsm, State1)