【问题标题】:Can't compile boost Meta State Machine with template argument无法使用模板参数编译 boost 元状态机
【发布时间】:2018-07-11 15:12:30
【问题描述】:

无法确定 TSm_ 中违反了哪条规则。 Sm_ 已编译,TSm_ 未编译:

错误 C2974:'boost::mpl::vector':'T0' 的模板参数无效, 预期类型

错误 C2974:“boost::mpl::vector”:“T3”的模板参数无效, 预期类型

区别在于 TSm_ 是模板,而 Sm_ 不是。

#include <boost/msm/back/state_machine.hpp>
#include <boost/msm/front/state_machine_def.hpp>

namespace msm = boost::msm;
namespace mpl = boost::mpl;

struct Event {};

class Sm_ : public msm::front::state_machine_def<Sm_>
{
public:
    using Me = Sm_;
    struct First : public msm::front::state<>
    {};
    using initial_state = First;
    struct Second : public msm::front::state<>
    {};
    void trans(const Event& /*e*/)
    {}
    struct transition_table : public mpl::vector<
        a_row<First, Event, Second, &Me::trans>
    >
    {};
};

using Sm = msm::back::state_machine<Sm_>;

// broken one

enum class Side : char
{
    Buy = 0, Sell = 1
};

template <Side side>
class TSm_ : public msm::front::state_machine_def<TSm_<side>>
{
public:
    using Me = TSm_<side>;
    using Base = msm::front::state_machine_def<Me>;
    using Base::a_row;
    struct First : public msm::front::state<>
    {};
    using initial_state = First;
    struct Second : public msm::front::state<>
    {};
    void trans(const Event& /*e*/)
    {}
    struct transition_table : public mpl::vector<
        a_row<First, Event, Second, &Me::trans> // compilation is failed here
    >
    {};
};

template <Side side>
using TSm = msm::back::state_machine<TSm_<side>>;

请帮忙

更新

我找到了编译的方法:a_row 不是类型而是模板,它的别名也应该是模板

struct Begin {};

template <Side side>
class TSm_ : public msm::front::state_machine_def<TSm_<side>>
{
public:
    //-----------------------------------------------------------------------------------------------------
    using Me = TSm_<side>;
    using Base = msm::front::state_machine_def<Me>;
    template<
        typename T1
        , class Event
        , typename T2
        , void (Me::*action)(Event const&)
    >
    using a_row = typename Base::a_row;
    //-----------------------------------------------------------------------------------------------------
    struct First : public msm::front::state<>
    {};
    //-----------------------------------------------------------------------------------------------------
    using initial_state = First;
    //-----------------------------------------------------------------------------------------------------
    struct Second : public msm::front::state<>
    {};
    //-----------------------------------------------------------------------------------------------------
    void trans(const Begin& /*e*/)
    {}
    //-----------------------------------------------------------------------------------------------------
    struct transition_table : public mpl::vector<
        a_row<First, Begin, Second, &Me::trans>
    >
    {};
};

是不是这个规则2) An alias template is a template which, when specialized, is equivalent to the result of substituting the template arguments of the alias template for the template parameters in the type-id

【问题讨论】:

    标签: c++ boost


    【解决方案1】:

    当你用模板状态机类定义转换表时,你可以使用rowa_rowg_row家族的functor前端。

    https://www.boost.org/doc/libs/1_67_0/libs/msm/doc/HTML/ch03s03.html

    如果你使用函子前端,你不需要关心msm::front::state_machine_def的子类是不是模板。

    这是基于你的更新代码:

    #include <iostream>
    
    #include <boost/msm/back/state_machine.hpp>
    #include <boost/msm/front/state_machine_def.hpp>
    
    // include functor_row
    #include <boost/msm/front/functor_row.hpp>
    
    namespace msm = boost::msm;
    namespace msmf = msm::front;
    namespace mpl = boost::mpl;
    
    struct Event {};
    
    // broken one
    
    enum class Side : char
    {
        Buy = 0, Sell = 1
    };
    
    template <Side side>
    class TSm_ : public msm::front::state_machine_def<TSm_<side>>
    {
    public:
        using Me = TSm_<side>;
        using Base = msm::front::state_machine_def<Me>;
        struct First : public msm::front::state<>
        {};
        using initial_state = First;
        struct Second : public msm::front::state<>
        {};
    
        // Replace the member function trans() with the functor trans.
        struct trans {
                template <class Fsm, class SourceState, class TargetState>
                void operator()(Event const&, Fsm&, SourceState&, TargetState&) const {
                std::cout << "called" << std::endl;
            }
        };
    
        struct transition_table : public mpl::vector<
                     //from     event    to      action,    guard
            msmf::Row <First,   Event,   Second, Me::trans, msmf::none >
            // This is functor front-end
        >
        {};
    };
    
    template <Side side>
    using TSm = msm::back::state_machine<TSm_<side>>;
    
    int main() {
        TSm<Side::Buy> sm;
        sm.start();
        sm.process_event(Event());
    }
    

    运行演示:https://wandbox.org/permlink/e9Qoc2xW3TTGhsmu

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-07-05
      • 1970-01-01
      • 2020-01-21
      • 2013-12-09
      • 1970-01-01
      • 2023-02-21
      • 1970-01-01
      相关资源
      最近更新 更多