为什么我使用 context().method() 违反了状态图断言?

2024-01-03

我已经为一个项目开发了一些概念代码,我很快就会从事该项目。该项目适合于状态机设计,我认为 boost::statechart 会做得很好。然而,当我尝试使用 context() 时,我遇到了障碍。这是一个示例(我很乐意提供更多代码,但我认为这是相关部分):

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

};

Active 状态具有名为“[over|under]flow_condition”的方法,此时该方法仅返回 true。抛开我的设计问题不谈,当我这样实例化时,我得到以下断言失败:

int main(void) {

  Throttler my_throttler;

  my_throttler.initiate();

  return 0;

}

这是断言:

断言“get_pointer( stt.pContext_ ) != 0" 失败

我在文件“/usr/include/boost/statechart/simple_state.hpp”第 689 行(boost 1.45)中查看了这个断言,注释说它是为了防止 simple_state 使用上下文。当我重新审视秒表示例并发现该示例正在做我想做的事情时,这让我感到困惑。所以我编译了它,毫不奇怪的是,秒表代码没有违反这个断言。我错过了什么吗?也许代码中的其他地方我错过了?这是整个标题(请记住它的概念代码......在它被彻底通用之前我不会将其发布到野外):

    #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

正如您在评论中指出的那样,它与尝试从构造函数内部访问外部上下文有关,这对于simple_state.

From simple_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 );

因此,如果您的状态基于state类(而不是simple_state).

也就是说,我不确定这可能会对你们的州产生什么影响或影响。如果这个问题 https://stackoverflow.com/questions/6529571/in-boost-statechart-whats-the-difference-between-state-and-simple-state得到答案可能对你也有帮助(:

据我了解,你需要改变Wait源自state:

 struct Wait : fsm::state< Wait, Active > {

然后更改Wait()构造函数类似

typedef fsm::state< Wait, Active > my_base;
Wait( my_context ctx ) : my_base( ctx )
// and any other pre-constructor initialisation...

The my_context类型被定义(受保护)state<>,并且需要从派生类的构造函数传入。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么我使用 context().method() 违反了状态图断言? 的相关文章

随机推荐

  • OS X 中 PyDev 和外部库的问题

    我已经在 OS X 10 6 3 下的 Eclipse 3 5 1 中成功安装了最新版本的 PyDev 使用 python 2 6 1我在使已安装的库正常工作时遇到了麻烦 例如 我正在尝试使用 cx Oracle 库 如果从使用某些文本编辑
  • IE7不理解显示:inline-block

    有人可以帮我解决这个错误吗 使用 Firefox 可以正常工作 但使用 Internet Explorer 7 则不行 貌似不太明白display inline block html div class frame header h2 h2
  • 使用 ETag 但状态代码始终为 200 而不是 304

    当我尝试请求http graph facebook com me fields friends http graph facebook com me fields friends使用 ETag 我每次都会得到请求代码 200 我们做了两次连
  • Java Spring MVC 在浏览器中显示 PDF

    如何强制浏览器显示 pdf 而不是下载 这是控制器 RequestMapping value preview pdf method RequestMethod GET protected String preivewSection Http
  • 将静态子域添加到网站的推荐方法是什么?

    我想创建一些静态子域 例如 mycategory mydomain com 在一个相当小的网站中 并希望它指向该文件夹 mydomain com mycategory 不在浏览器地址栏中显示此类重定向 实现它的最简单方法是什么 我可以在 I
  • 吸收 HTML 元素的宽度

    我正在思考如何使用 html 元素来做到这一点 颜色没有什么特别的 所以我不需要把它们做成图像 请注意 文本是右对齐的 此外 颜色条从左侧上升到文本 因此 这可以通过让文本向右浮动 背景颜色为白色 并在其旁边设置一个背景颜色的 div 然后
  • 将事件监听器添加到未来的项目(没有 jQuery)[重复]

    这个问题在这里已经有答案了 很好奇我是否愿意接受用 Vanilla JS 编写列表应用程序的挑战 问题是事件监听器没有添加到新的列表项中 我向列表中的现有项目添加删除按钮 const deleteButton document queryS
  • 为什么数字的行为与有序的不同?

    Scala 有许多可以用作类型类的特征 例如Ordered and Numeric包装内scala math 例如 我可以使用编写一个通用方法Ordered像这样 def f T
  • Request.Url.Host 和 ApplicationPath 一次调用

    有什么办法可以得到HttpContext Current Request Url Host and HttpContext Current Request ApplicationPath一通电话 像 完整的应用程序网址 之类的东西 编辑 澄
  • 如何在 Swift 中将字典切片转换为字典

    我正在尝试转换myDictionary dropFirst 一本新字典缺少一个键 我不在乎是哪一个 dropFirst 返回一个切片 我想要一本与以下类型相同的新词典myDictionary 您可以将数组切片转换为数组 如下所示let ar
  • 类型“Observable<{}>”不可分配给类型“Observable”

    前言 我知道还有很多其他问题也有同样的错误 但我似乎仍然无法弄清楚我自己的问题 我有一个简单的服务和另一个简单的组件 我正在尝试非常严格地遵循 angular2 英雄教程 这是我的代码 位置 ts export class Location
  • 使用 Segue 发送变量

    我正在开发一个简单的 iOS Swift 应用程序 该应用程序有 2 个视图控制器和一个已编程为连接到另一个视图控制器的按钮 如下所示 IBAction func pushMe sender AnyObject self performSe
  • 将列表中的学生姓名和年龄添加到列表框

    我有 3 个textboxes我可以在哪里进入Name Surname and Age 当我按下按钮1后 它会生成一个具有这些属性的新学生 如何将具有所有 3 个属性的学生添加到ListBox 看起来像这样 姓名 姓氏 年龄1 约翰 史密斯
  • WP7 - 在“重建”时擦除独立存储设置

    我刚刚发现 困难的方法 如果您在 Visual Studio 中执行 重建 或 清理 gt 构建 后将应用程序部署到设备 您的应用程序将首先被卸载 然后重新安装 导致隔离的存储文件被擦除 应用程序部署工具似乎总是会卸载 重新安装 无论它是否
  • Java Instant.parse 日期 java 8

    我有一些旧版 KML 文档 其中包含时间戳条目 为什么使用 Instant 解析时以下日期无效 这两种方法都假设解析 ISO 8601 格式的日期 字符串日期字符串 2017 12 04T08 06 60Z Using java time
  • 您能否将 Google Cloud 网络控制台登录限制在某个 IP 地址范围内?

    我在使用 Google Cloud Platform 特别是我工作的 IT 安全部门的 Big Query 时遇到了一些阻力 争论的焦点是任何人都可以从任何地方登录 有什么办法只允许来自特定 IP 范围的 GCP 访问吗 或者是否有其他方法
  • Azure 函数请求正文为 xml 而不是 json

    我正在跟进这个例子 https learn microsoft com en us azure azure functions functions test a function在 Azure 函数中创建 javascript 函数并使用
  • php 的 mysql_real_escape_string() 的等效 JavaScript 代码是什么?

    等效的 javascript 代码是什么mysql real escape string 基于PHP 文档 http php net manual en function mysql real escape string php该方法的作用
  • 如何在 felm() 函数之后绘制交互的边际效应

    我基于具有一堆单位固定效应的 巨大 面板数据进行了回归 所以我使用了包 lfe 中的函数 felm 此外 我在回归中有两个连续变量的交互项 但是 当绘制 x 对 y 的边际效应如何随 x2 变化时 felm 生成的对象似乎通常与大多数绘图函
  • 为什么我使用 context().method() 违反了状态图断言?

    我已经为一个项目开发了一些概念代码 我很快就会从事该项目 该项目适合于状态机设计 我认为 boost statechart 会做得很好 然而 当我尝试使用 context 时 我遇到了障碍 这是一个示例 我很乐意提供更多代码 但我认为这是相