【问题标题】:Boost MSM compilation speedup提高 MSM 编译速度
【发布时间】:2018-04-25 07:38:02
【问题描述】:

我正在尝试通过使用 boost MSM 状态机的显式模板实例化来减少项目的编译时间。但是,每当我添加显式模板实例化时,我的项目都不会编译。

您可以使用以下文档中的示例找到问题示例:http://coliru.stacked-crooked.com/a/9850cae23afdada2。 (这是一个人为的例子,因为只有一个翻译单元,但错误与我在项目中使用显式模板实例化时的错误相同。)

有人知道如何解决这些编译错误吗?

/usr/local/include/boost/msm/back/state_machine.hpp: In instantiation of 'boost::msm::back::state_machine<A0, A1, A2, A3, A4>::deferred_events_queue_t& boost::msm::back::state_machine<A0, A1, A2, A3, A4>::get_deferred_queue() [with A0 = player_; A1 = boost::parameter::void_; A2 = boost::parameter::void_; A3 = boost::parameter::void_; A4 = boost::parameter::void_; boost::msm::back::state_machine<A0, A1, A2, A3, A4>::deferred_events_queue_t = std::deque<std::pair<boost::function<boost::msm::back::HandledEnum()>, bool>, std::allocator<std::pair<boost::function<boost::msm::back::HandledEnum()>, bool> > >]':
main.cpp:271:27:   required from here
/usr/local/include/boost/msm/back/state_machine.hpp:1346:40: error: 'struct boost::msm::back::state_machine<player_>::deferred_msg_queue_helper<boost::msm::back::state_machine<player_>, int>' has no member named 'm_deferred_events_queue'
         return m_deferred_events_queue.m_deferred_events_queue;
                ~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~
...

【问题讨论】:

  • 您是否已经将文档中的建议应用到您的项目中?对我来说,模板实例化路线看起来像是一个微优化。 boost.org/doc/libs/1_67_0/libs/msm/doc/HTML/…
  • @AlessandroTeruzzi 我考虑过模板实例化,因为我在测试中使用 FSM,并且在每个 TU 中都会重新编译它。我的目标是在测试(以及项目源代码)中使用 extern 模板类,并且只有一个特定的文件用于实例化,以便只编译一次。
  • @AlessandroTeruzzi 我尝试使用喜爱编译时间策略,但正如我所料,影响不大。也许我应该尝试将我的 FSM 拆分成更小的部分。

标签: c++ boost boost-msm


【解决方案1】:

不幸的是,由于some differences between how explicit and implicit instantiation work,您尝试做的事情不起作用:

隐式实例化

如果您隐式实例化模板(就像您通常使用状态机时那样),编译器不一定会为所有成员函数生成代码:

类模板特化的隐式实例化原因

  • 非删除类成员函数、成员类、作用域成员枚举、静态数据成员、成员模板和友元的声明而非定义的隐式实例化

C++ standard draft, [temp.inst/2]

显式实例化

当您显式实例化模板时(如您在上面尝试的那样),编译器会将 每个 成员函数视为显式实例化,这意味着它也会尝试编译它们。

命名类模板特化的显式实例化也是其每个成员(不包括从基类继承的成员和模板成员)的同类(声明或定义)的显式实例化[。 ..]

C++ standard draft, [temp.explicit/10]

与 MSM

在这种特殊情况下,区别在于get_deferred_queue 成员函数。仅当deferred_msg_queue_helper 提供特定成员时才会编译,仅当您的州支持延迟事件时才会编译。通常,您不会调用该函数,因此编译器永远不会尝试实例化然后编译它。但是,显式实例化使编译器尝试 - 并且失败 - 在您的状态机中编译 get_deferred_queue。显然,this is desired standard behavior,因此您唯一的解决方法是在您的状态机中支持延迟事件,如 in the documentation 所述

不幸的是,您很可能会遇到其他通常在编译时关闭的功能的其他问题。我遇到的下一个问题涉及visit_current_states 函数——为了解决这个问题,我必须添加一个自定义基本状态,其中包含here 所述的访问者功能。 让它编译时没有错误,尽管我不完全确定这些更改实际会产生什么影响。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-27
    • 1970-01-01
    • 1970-01-01
    • 2010-09-14
    • 1970-01-01
    • 2017-08-22
    相关资源
    最近更新 更多