C++ 具有 tinyfsm 的循环类依赖 - 前向声明不起作用



我遇到以下代码的问题:

#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> 

这在全局命名空间中声明了一个名为Fsmstruct

标头在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)

最新更新