代码之家  ›  专栏  ›  技术社区  ›  wtom

无法使用模板参数编译Boost元状态机

  •  1
  • wtom  · 技术社区  · 8 年前

    无法找出在中违反了哪个规则 TSM公司_ 是的。 山猫_ 是编译的, TSM公司_ 不是:

    错误C2974:“boost::mpl::vector”:“t0”的模板参数无效, 需要类型

    错误C2974:“boost::mpl::vector”:“t3”的模板参数无效, 需要类型

    区别在于 TSM公司_ 是一个模板 山猫_ 不是。

    #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>>;
    

    请帮忙

    更新

    我找到了如何编译它的方法:因为行不是类型而是模板,所以它的别名也应该是模板

    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 是吗?

    1 回复  |  直到 8 年前
        1
  •  1
  •   Takatoshi Kondo    8 年前

    用模板状态机类定义转换表时,可以使用functor前端代替 row 我是说, a_row g_row 家人。

    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