Увеличьте скорость компиляции MSM

Я пытаюсь сократить время компиляции моего проекта, используя явное создание экземпляра шаблона конечного автомата 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;
                ~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~
...

person slepasteur    schedule 25.04.2018    source источник
comment
вы уже применили предложения в документации к вашему проекту? Маршрут создания экземпляра шаблона выглядит для меня как микрооптимизация. boost.org/doc/libs/ 1_67_0/libs/msm/doc/HTML/   -  person Alessandro Teruzzi    schedule 25.04.2018
comment
@AlessandroTeruzzi Я думал о создании экземпляра шаблона, потому что я использую FSM в тестах, и он перекомпилируется в каждом TU. Моя цель - использовать класс шаблона extern в тестах (а также в исходниках проекта), и просто иметь один конкретный файл для создания экземпляра, чтобы он компилировался только один раз.   -  person slepasteur    schedule 25.04.2018
comment
@AlessandroTeruzzi Я пытался использовать политику Favor_compile_time, но, как я и ожидал, эффект невелик. Может быть, мне стоит попробовать разбить мой FSM на более мелкие.   -  person slepasteur    schedule 25.04.2018


Ответы (1)


То, что вы пытаетесь сделать, к сожалению, не работает из-за некоторых различий между явным и неявным работа по созданию экземпляра:

Неявное создание экземпляра

Если вы неявно создаете экземпляр шаблона (как обычно при использовании конечного автомата), компилятор не обязательно будет генерировать код для всех функций-членов:

Неявное создание экземпляра специализации шаблона класса вызывает

  • неявное создание экземпляров объявлений, но не определений, неудаленных функций-членов класса, классов-членов, перечислений членов с ограниченной областью действия, членов статических данных, шаблонов членов и друзей.

черновик стандарта C++, [temp.inst/2]

Явное создание экземпляра

Когда вы явно создаете экземпляр шаблона (как вы пытались выше), компилятор будет рассматривать каждую функцию-член как явно созданную, что означает, что он также попытается скомпилировать их.

Явное воплощение, именующее специализацию шаблона класса, также является явным воплощением того же типа (объявлением или определением) каждого из его членов (не включая членов, унаследованных от базовых классов, и членов, являющихся шаблонами) [...]

стандартный проект C++, [temp.explicit/10]< / суп>

С МСМ

В данном конкретном случае разница заключается в функции-члене get_deferred_queue. Он будет скомпилирован только в том случае, если deferred_msg_queue_helper предлагает определенный элемент, что возможно только в том случае, если ваши состояния поддерживают отложенные события. Обычно вы не вызываете эту функцию, поэтому компилятор никогда не пытается создать экземпляр, а затем скомпилировать его. Однако явное создание экземпляра заставляет компилятор пытаться - и безуспешно - скомпилировать get_deferred_queue в вашей конечной машине. По-видимому, это желаемое стандартное поведение, поэтому единственный обходной путь для вас - поддерживать отложенные события в вашем конечном автомате, как описано в документации

К сожалению, весьма вероятно, что вы столкнетесь с дополнительными проблемами с другими функциями, которые обычно отключаются во время компиляции. Следующая проблема, с которой я столкнулся, связана с функцией visit_current_states. Чтобы исправить это, мне пришлось добавить пользовательское базовое состояние с функциями посетителя, как описано здесь. Это позволило скомпилировать его без ошибок, хотя я не совсем уверен, какое влияние на самом деле оказали эти изменения.

person hlt    schedule 03.05.2018