Boost 为什么我使用上下文<;国家>;().method()违反状态图断言?
我已经为一个项目开发了一些概念代码,我很快就要开始工作了。该项目适合于状态机设计,我认为boost::statechart会做得很好。然而,当我尝试使用context()时遇到了一个障碍。下面是一个示例(我很高兴提供更多代码,但我认为这是相关的部分): 这是一个断言: 断言“获取指针(stt.pContext_ )!=0“失败 我在文件“/usr/include/boost/statechart/simple_state.hpp”第689行(boost 1.45)中查找了这个断言,评论说它是为了防止simple_state使用上下文。当我重温stopwatch示例时,这让我感到困惑,我发现该示例正是在做我想做的事情。所以我编译了它,毫无疑问stopwatch代码没有违反这个断言。我错过什么了吗?也许在代码的其他地方我遗漏了什么?这是整个标题(请记住它是概念代码…在它被完全泛化之前,我不会将其发布到野外):Boost 为什么我使用上下文<;国家>;().method()违反状态图断言?,boost,boost-statechart,Boost,Boost Statechart,我已经为一个项目开发了一些概念代码,我很快就要开始工作了。该项目适合于状态机设计,我认为boost::statechart会做得很好。然而,当我尝试使用context()时遇到了一个障碍。下面是一个示例(我很高兴提供更多代码,但我认为这是相关的部分): 这是一个断言: 断言“获取指针(stt.pContext_ )!=0“失败 我在文件“/usr/include/boost/statechart/simple_state.hpp”第689行(boost 1.45)中查找了这个断言,评论说它是为了
\ifndef\u节流阀_
#定义节流阀_
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
名称空间mpl=boost::mpl;
名称空间fsm=boost::statechart;
名称空间{
无符号整数默认等待时间(1000);
}
结构noop{
公众:
noop(){m_priority=(1{};
结构活跃;
结构节流器:fsm::state_machine{};
结构等待;
struct-Active:fsm::simple_-state{
公众:
类型定义mpl::列表>反应;
bool溢出_条件(void){return true;}
布尔下溢_条件(void){返回真;}
无效队列操作(noop op){
m_操作_队列推送(op);
}
作废执行_操作(作废){
noop op(m_operation_queue.top());
if(op())
m_操作_queue.pop();
其他的
投掷;
}
私人:
std::优先级队列、操作队列;
私人:
std::优先级队列、操作队列;
};
struct Exec:fsm::simple_state{
类型定义mpl::列表>反应;
Exec(){std::cout正如您在评论中所指出的,它与尝试从构造函数中访问外部上下文有关,这对于简单\u状态是不允许的
从simple\u state.hpp
:
// This assert fails when an attempt is made to access the state machine
// from a constructor of a state that is *not* a subtype of state<>.
// To correct this, derive from state<> instead of simple_state<>.
BOOST_ASSERT( get_pointer( pContext_ ) != 0 );
然后将Wait()
构造函数更改为
typedef fsm::state< Wait, Active > my_base;
Wait( my_context ctx ) : my_base( ctx )
// and any other pre-constructor initialisation...
typedef fsm::statemy_base;
等待(my_context ctx):my_base(ctx)
//以及任何其他预构造函数初始化。。。
my_context
类型在state
中定义(被保护),需要从派生类的构造函数中传入。我想我可能已经解决了这个问题。我正在调用wait()来自Wait的构造函数。显然这是不允许的…我不敢相信我错过了!谢谢@drfrogsplat!事实上我已经发现了更多关于它的内容…你也需要修改构造函数,根据链接问题中的答案/评论(用我希望对你正确的信息更新了答案)sry我之前没有给你打勾!我想这是我在上的第一篇帖子。
#ifndef _THROTTLER_H_
#define _THROTTLER_H_
#include<queue>
#include<vector>
#include<ctime>
#include<boost/statechart/event.hpp>
#include<boost/statechart/transition.hpp>
#include<boost/statechart/state_machine.hpp>
#include<boost/statechart/simple_state.hpp>
#include<boost/mpl/list.hpp>
#include<iostream>
namespace mpl = boost::mpl;
namespace fsm = boost::statechart;
namespace {
unsigned int DEFAULT_WAIT_TIME(1000);
}
struct noop {
public:
noop() { m_priority = (1 << sizeof(int)); }
noop(unsigned int priority) { m_priority = priority; }
virtual ~noop() {}
bool operator()(void) {
return true;
}
friend bool operator<(noop a, noop b);
private:
unsigned int m_priority;
};
bool operator<(noop a, noop b) {
return a.m_priority < b.m_priority;
}
struct compare_noops {
bool operator()(noop a, noop b) {
}
};
struct default_wait {
void operator()(unsigned long msecs = DEFAULT_WAIT_TIME) {
std::clock_t endtime =
std::clock() + (msecs*1000*CLOCKS_PER_SEC);
while(clock() < endtime);
}
};
struct OverflowEvent : fsm::event< OverflowEvent > {};
struct UnderflowEvent : fsm::event< UnderflowEvent > {};
struct ResetEvent : fsm::event< ResetEvent > {};
struct Active;
struct Throttler : fsm::state_machine< Throttler, Active > {};
struct Wait;
struct Active : fsm::simple_state< Active, Throttler, Wait > {
public:
typedef mpl::list<fsm::transition< ResetEvent, Active> > reactions;
bool overflow_condition(void) { return true; }
bool underflow_condition(void) { return true; }
void queue_operation(noop op) {
m_operation_queue.push(op);
}
void perform_operation(void) {
noop op(m_operation_queue.top());
if(op())
m_operation_queue.pop();
else
throw;
}
private:
std::priority_queue<noop, std::vector<noop>, compare_noops > m_operation_queue;
private:
std::priority_queue<noop, std::vector<noop>, compare_noops > m_operation_queue;
};
struct Exec : fsm::simple_state< Exec, Active > {
typedef mpl::list<fsm::transition< OverflowEvent, Wait> > reactions;
Exec() { std::cout << "entering exec state." << std::endl; }
~Exec() { std::cout << "exiting exec state." << std::endl; }
};
struct Wait : fsm::simple_state< Wait, Active > {
typedef mpl::list<fsm::transition< UnderflowEvent, Exec> > reactions;
public:
Wait()
: m_wait_op() {
std::cout << "entering wait state." << std::endl;
wait();
}
~Wait() { std::cout << "exiting wait state." << std::endl; }
private:
default_wait m_wait_op;
fsm::result wait() {
if(context<Active>().underflow_condition()) {
m_wait_op();
return transit<Wait>();
}
else if(context<Active>().overflow_condition()) {
return transit<Exec>();
}
else {
// undefined - keep waiting
}
}
};
#endif
// This assert fails when an attempt is made to access the state machine
// from a constructor of a state that is *not* a subtype of state<>.
// To correct this, derive from state<> instead of simple_state<>.
BOOST_ASSERT( get_pointer( pContext_ ) != 0 );
struct Wait : fsm::state< Wait, Active > {
typedef fsm::state< Wait, Active > my_base;
Wait( my_context ctx ) : my_base( ctx )
// and any other pre-constructor initialisation...