【问题标题】:[Boost::ext].SML: Access SM and dependencies in an action[Boost::ext].SML:在操作中访问 SM 和依赖项
【发布时间】:2021-01-21 06:10:55
【问题描述】:

我正在使用 SML (https://boost-ext.github.io/sml/) v.1.1.3,我需要访问注入的依赖项和操作中的状态机。 根据以下提交,这应该已经可以工作了:https://github.com/boost-ext/sml/commit/e6d0685993a8a0160dde1610d7f8be4f811c89d0 此提交是此问题的结果: https://github.com/boost-ext/sml/issues/94

在接下来的示例中,我尝试访问 action2 中的依赖项和 sm,但出现编译错误: ... sml.hpp:1853:18:注意:无法转换 'deps'(类型 'boost::ext::sml::v1_1_3::aux::pool') 输入'int&' 1853 |返回对象(事件、sm、deps、subs);

例子:

#include <boost/sml.hpp>
#include <cassert>
#include <iostream>

namespace sml = boost::sml;

namespace {
 
struct e1 {};
struct e2 {};
struct e3 {};

auto action2 = [](const auto& event, auto& sm, int& i, std::string& str) {
    assert(42 == i);
    std::cout << "action2" << std::endl;
    std::cout << "sm.n: " << sm.n << std::endl;
};

struct actions_guards {
    using self = actions_guards;

    int n = 10;

    auto operator()() {
        using namespace sml;

        auto action1 = [](auto e) { std::cout << "action1: " << typeid(e).name() << std::endl; };

        auto guard1 = [](int i) {
            assert(42 == i);
            std::cout << "guard2" << std::endl;
            return false;
        };

        return make_transition_table(
            //  Start           Event             Guard                         Action                        Next
            //+-------------+-------------------+---------------------------+-------------------------------+-------------------------------+
                *"idle"_s   +   event<e1>       [ guard1 ]                  /   action1                     = "s1"_s,
                "s1"_s      +   event<e2>       [ &self::guard2 ]           /   action2                     = "s2"_s,
                "s2"_s      +   event<e3>                                                                   = X
        );
    }

    bool guard2(int i) const noexcept {
        assert(42 == i);
        std::cout << "guard3" << std::endl;
        return true;
    }
};

}  // namespace

int main( int argc, char* argv[] )
{
    actions_guards ag{};
    std::string strDep( "127.0.0.1" );
    int intDep = 42;
    sml::sm<actions_guards> sm{ag, intDep, strDep};
    sm.process_event(e1{});
    sm.process_event(e2{});
    sm.process_event(e3{});

    assert(sm.is(sml::X));

    return 0;
}

错误: ... sml.hpp:1340:10: 来自 'bool boost::ext::sml::v1_1_3::back::sm_impl::process_event(const TEvent&, TDeps&, TSubs&) [with TEvent = {anonymous}:: e2; TDeps = boost::ext::sml::v1_1_3::aux::pool; TSubs = boost::ext::sml::v1_1_3::aux::poolboost::ext::sml::v1_1_3::back::sm_impl<:ext::sml::v1_1_3::back::sm_policy>>; TSM = boost::ext::sml::v1_1_3::back::sm_policy]' /usr/local/oecore-x86_64_tux_dunfell/sysroots/armv5te-angstrom-linux-gnueabi/usr/include/boost/sml.hpp:1660:81:需要来自'bool boost::ext::sml::v1_1_3::back ::sm::process_event(const TEvent&) [with TEvent = {anonymous}::e2;类型名 boost::ext::sml::v1_1_3::aux::enable_if<:ext::sml::v1_1_3::aux::integral_constant __is_base_of boost::ext::sml:: v1_1_3::back::sm::events_ids>::value, int>::type = 0; TSM = boost::ext::sml::v1_1_3::back::sm_policy]' main.cpp:86:23:从这里需要 /usr/local/oecore-x86_64_tux_dunfell/sysroots/armv5te-angstrom-linux-gnueabi/usr/include/boost/sml.hpp:1853:18:错误:不匹配调用'(boost::ext::sml: :v1_1_3::aux::zero_wrapper, void>) (const {anonymous}::e2&, boost:: ext::sml::v1_1_3::back::sm_implboost::ext::sml::v1_1_3::back::sm_policy&, boost::ext::sml::v1_1_3:: aux::pool&, boost::ext::sml::v1_1_3::aux::poolboost::ext::sml::v1_1_3:: back::sm_impl<:ext::sml::v1_1_3::back::sm_policy> >&)' 1853 |返回对象(事件、sm、deps、subs); | ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~ main.cpp:37:16:注意:候选:'template {anonymous}:: ' 37 | auto action2 = [](const auto& event, auto& sm, int& i, std::string& str) { | ^ main.cpp:37:16:注意:模板参数扣除/替换失败: 在 main.cpp:20 包含的文件中: /usr/local/oecore-x86_64_tux_dunfell/sysroots/armv5te-angstrom-linux-gnueabi/usr/include/boost/sml.hpp:1853:18:注意:不能转换'deps'(输入'boost::ext::sml ::v1_1_3::aux::pool') 输入'int&' 1853 |返回对象(事件、sm、deps、subs); | ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~

【问题讨论】:

    标签: c++ boost c++14 state-machine boost-extension


    【解决方案1】:

    期末SML作者的回答#399

    此功能的实现已更改以避免递归调用并符合 UML-2.5

    例子

    s1 + event<e1> / [](sml::back::process<e2, e3> processEvent) -> void {
                processEvent(e2{});
                processEvent(e3{});
              }
    

    定义sm时必须指定process_queue

    sml::sm<c, sml::process_queue<std::queue>> sm{};
    

    Full example

    这里是我实际问题的改编示例:

    #include <iostream>
    #include <cassert>
    #include <queue>
    #include <boost/sml.hpp>
    
    namespace sml = boost::sml;
    
    struct e1 {};
    struct e2 {};
    struct e3 {};
    
    struct my_dep {
        int val = 0;
    };
    
    auto action = [](sml::back::process<e2, e3> processEvent, my_dep& dep) {
        if (dep.val == 0) {
            processEvent(e2{});
            ++dep.val;
        }
        else
            processEvent(e3{});
    };
    
    struct table {
        auto operator()() const noexcept {
            using namespace sml;
            return make_transition_table(
                *"s1"_s + event<e1> / action = "s3"_s
                ,"s1"_s + event<e2> = "s2"_s
                ,"s3"_s + event<e2> = "s4"_s
                ,"s3"_s + event<e3> = "s5"_s
                ,"s4"_s + event<e1> = "s1"_s
            );
        }
    };
    
    int main() {
        using namespace sml;
        my_dep md;
        sm<table, sml::process_queue<std::queue>> sm{md};
    
        sm.process_event(e1{});
        assert(sm.is("s4"_s));
    
        sm.process_event(e1{});
        assert(sm.is("s1"_s));
    
        sm.process_event(e1{});
        assert(sm.is("s5"_s));
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-01
      • 2017-07-29
      • 1970-01-01
      相关资源
      最近更新 更多