2

我试图通过使用 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;
                ~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~
...
4

1 回答 1

4

不幸的是,由于显式和隐式实例化的工作方式之间存在一些差异,您正在尝试做的事情不起作用:

隐式实例化

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

类模板特化的隐式实例化导致

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

C++ 标准草案,[temp.inst/2]

显式实例化

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

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

C++ 标准草案,[temp.explicit/10]

与男男性接触者

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

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

于 2018-05-03T09:40:47.693 回答