Следующий код не компилируется:
namespace sc = boost::statechart;
class Active;
class FSM : public sc::state_machine< FSM, startup>
{
};
class ev_1 : public sc::event<ev_1> {};
class ev_2 : public sc::event<ev_2> {};
class Active : public sc::simple_state< Active, FSM >
{
public:
typedef boost::mpl::list<
sc::custom_reaction< ev_1 >,
sc::custom_reaction< ev_2 >
> reactions;
sc::result react( const ev_1 & );
sc::result react( const ev_2 & );
};
class state_1 : public sc::simple_state< state_1, Active >
{
public:
state_1(){};
~state_1(){};
};
class state_2 : public sc::simple_state< state_2, Active >
{
public:
state_2(){};
~state_2(){};
};
sc::result startup::react( const ev_1 & )
{
return transit< state_1 >();
}
sc::result startup::react( const ev_2 & )
{
return transit< state_2 >();
}
Проблема, похоже, заключается в том, что активное состояние должно определять свое дочернее состояние в своем определении. Например, если я сделаю следующее:
class Active : public sc::simple_state< Active, FSM, state_1 > { ... };
компиляция приводит к успеху. Могу ли я не указывать на состояние по умолчанию?
Постскриптум Часть ошибки компиляции, которую я нашел существенной, говорит: simple_state.hpp:388: error: invalid application of ‘sizeof’ to incomplete type ‘boost_1_49_0::STATIC_ASSERTION_FAILURE<false>’
но это ничего не говорит мне.
Нет, вы не можете иметь подсостояния без одного из них по умолчанию. Это не ограничение из диаграмм состояний, а скорее часть концепции конечных автоматов в целом. Представьте, что вы переходите к Action
По определению одно из подсостояний также должно быть введено, и SM должен знать, в какое из них войти.
Если логического значения по умолчанию нет и вы всегда явно переходите к конечным состояниям, тогда действительно не нужно быть значением по умолчанию, но диаграммы состояний по-прежнему нуждаются в значении по умолчанию. Вы всегда можете создать третье дочернее состояние «ничего не делать», которое используется по умолчанию. Если вы никогда не переходите к Active
а скорее всегда state_1
или же state_2
непосредственно тогда ваше фиктивное состояние по умолчанию будет оптимизировано в любом случае, так что это хорошая работа.
Других решений пока нет …