在子机器上使用构造函数参数提升 MSM
Boost MSM with constructor parameters on a submachine
我正在尝试在主状态机和子状态机之间共享 SyncBox
对象。理想的方法是将其传递给构造函数(在更复杂的情况下,子状态机将是其中一个区域的初始状态)。无论如何,我都无法使这段代码正常编译和执行。有帮助吗?
#include <iostream>
#include <mutex>
#include <boost/msm/back/state_machine.hpp>
#include <boost/msm/front/state_machine_def.hpp>
#include <boost/msm/front/functor_row.hpp>
#include <boost/msm/front/euml/common.hpp>
namespace msm = boost::msm;
namespace mpl = boost::mpl;
using namespace boost::msm::front;
class SyncBox {
std::mutex mtx;
};
struct SubSMFE : public msm::front::state_machine_def<SubSMFE>
{
struct InitState : public msm::front::state<> {};
struct FakeState : public msm::front::state<> {};
typedef InitState initial_state;
struct transition_table : mpl::vector<
Row < InitState, none, FakeState>
> {};
};
//typedef msm::back::state_machine<SubSMFE> SubSM;
class SubSM : public msm::back::state_machine<SubSMFE> {
private:
SyncBox& sb;
public:
SubSM(SyncBox& sb) : sb(sb) { std::cout << "SubSMFE constructor" << std::endl; };
void oneFunction() {
// here i use syncBox. it must be a function of SubSM, not SubSMFE (oneFunction overrides start or enqueue_event)
};
};
struct mainSMFE : public msm::front::state_machine_def<mainSMFE>
{
protected:
SyncBox sb;
public:
struct InitState : public msm::front::state<> {};
typedef InitState initial_state;
struct transition_table : mpl::vector<
Row < InitState, none, SubSM>
> {};
};
class mainSM : public msm::back::state_machine<mainSMFE> {
public:
mainSM() : msm::back::state_machine<mainSMFE>(msm::back::states_ << SubSM(sb)) { };
};
int main()
{
mainSM sm;
return 0;
}
据我所知,你的一切都是正确的。
然而,问题是子状态列表要求所有状态元素无论如何都是可默认构造的。 (据我所知,这对于前端 class 可能不正确,但还没有深入研究)。
这意味着将引用存储为成员是禁止的。我建议的是存储一个指针。
class SubSM : public msm::back::state_machine<SubSMFE> {
private:
SyncBox* psb = nullptr;
public:
SubSM() = default;
SubSM(SyncBox& psb)
: psb(&psb)
{
std::cout << "SubSMFE constructor" << std::endl;
};
它确实按预期工作:
#include <boost/msm/back/state_machine.hpp>
//#include <boost/msm/front/euml/common.hpp>
#include <boost/msm/front/functor_row.hpp>
#include <boost/msm/front/state_machine_def.hpp>
#include <iostream>
#include <mutex>
namespace msm = boost::msm;
namespace mpl = boost::mpl;
using namespace boost::msm::front;
class SyncBox {
std::mutex mtx;
};
struct SubSMFE : public msm::front::state_machine_def<SubSMFE> {
struct InitState : public msm::front::state<> { };
struct FakeState : public msm::front::state<> { };
using initial_state = InitState;
// clang-format off
struct transition_table : mpl::vector<
Row < InitState, none, FakeState>
> {};
// clang-format on
};
// typedef msm::back::state_machine<SubSMFE> SubSM;
class SubSM : public msm::back::state_machine<SubSMFE> {
private:
SyncBox* psb = nullptr;
public:
SubSM() = default;
explicit SubSM(SyncBox& psb)
: psb(&psb)
{
std::cout << "SubSMFE constructor" << std::endl;
};
void oneFunction() {
// here i use syncBox. it must be a function of SubSM, not SubSMFE
// (oneFunction overrides start or enqueue_event)
};
};
class mainSMFE : public msm::front::state_machine_def<mainSMFE> {
protected:
SyncBox sb;
public:
struct InitState : public msm::front::state<> { };
using initial_state = InitState;
// clang-format off
struct transition_table : mpl::vector<
Row < InitState, none, SubSM >
> {};
// clang-format on
};
class mainSM : public msm::back::state_machine<mainSMFE> {
public:
mainSM()
: msm::back::state_machine<mainSMFE>(
msm::back::states_ << SubSM(sb)) {};
};
int main() {
mainSM sm;
}
版画
SubSMFE constructor
我正在尝试在主状态机和子状态机之间共享 SyncBox
对象。理想的方法是将其传递给构造函数(在更复杂的情况下,子状态机将是其中一个区域的初始状态)。无论如何,我都无法使这段代码正常编译和执行。有帮助吗?
#include <iostream>
#include <mutex>
#include <boost/msm/back/state_machine.hpp>
#include <boost/msm/front/state_machine_def.hpp>
#include <boost/msm/front/functor_row.hpp>
#include <boost/msm/front/euml/common.hpp>
namespace msm = boost::msm;
namespace mpl = boost::mpl;
using namespace boost::msm::front;
class SyncBox {
std::mutex mtx;
};
struct SubSMFE : public msm::front::state_machine_def<SubSMFE>
{
struct InitState : public msm::front::state<> {};
struct FakeState : public msm::front::state<> {};
typedef InitState initial_state;
struct transition_table : mpl::vector<
Row < InitState, none, FakeState>
> {};
};
//typedef msm::back::state_machine<SubSMFE> SubSM;
class SubSM : public msm::back::state_machine<SubSMFE> {
private:
SyncBox& sb;
public:
SubSM(SyncBox& sb) : sb(sb) { std::cout << "SubSMFE constructor" << std::endl; };
void oneFunction() {
// here i use syncBox. it must be a function of SubSM, not SubSMFE (oneFunction overrides start or enqueue_event)
};
};
struct mainSMFE : public msm::front::state_machine_def<mainSMFE>
{
protected:
SyncBox sb;
public:
struct InitState : public msm::front::state<> {};
typedef InitState initial_state;
struct transition_table : mpl::vector<
Row < InitState, none, SubSM>
> {};
};
class mainSM : public msm::back::state_machine<mainSMFE> {
public:
mainSM() : msm::back::state_machine<mainSMFE>(msm::back::states_ << SubSM(sb)) { };
};
int main()
{
mainSM sm;
return 0;
}
据我所知,你的一切都是正确的。
然而,问题是子状态列表要求所有状态元素无论如何都是可默认构造的。 (据我所知,这对于前端 class 可能不正确,但还没有深入研究)。
这意味着将引用存储为成员是禁止的。我建议的是存储一个指针。
class SubSM : public msm::back::state_machine<SubSMFE> {
private:
SyncBox* psb = nullptr;
public:
SubSM() = default;
SubSM(SyncBox& psb)
: psb(&psb)
{
std::cout << "SubSMFE constructor" << std::endl;
};
它确实按预期工作:
#include <boost/msm/back/state_machine.hpp>
//#include <boost/msm/front/euml/common.hpp>
#include <boost/msm/front/functor_row.hpp>
#include <boost/msm/front/state_machine_def.hpp>
#include <iostream>
#include <mutex>
namespace msm = boost::msm;
namespace mpl = boost::mpl;
using namespace boost::msm::front;
class SyncBox {
std::mutex mtx;
};
struct SubSMFE : public msm::front::state_machine_def<SubSMFE> {
struct InitState : public msm::front::state<> { };
struct FakeState : public msm::front::state<> { };
using initial_state = InitState;
// clang-format off
struct transition_table : mpl::vector<
Row < InitState, none, FakeState>
> {};
// clang-format on
};
// typedef msm::back::state_machine<SubSMFE> SubSM;
class SubSM : public msm::back::state_machine<SubSMFE> {
private:
SyncBox* psb = nullptr;
public:
SubSM() = default;
explicit SubSM(SyncBox& psb)
: psb(&psb)
{
std::cout << "SubSMFE constructor" << std::endl;
};
void oneFunction() {
// here i use syncBox. it must be a function of SubSM, not SubSMFE
// (oneFunction overrides start or enqueue_event)
};
};
class mainSMFE : public msm::front::state_machine_def<mainSMFE> {
protected:
SyncBox sb;
public:
struct InitState : public msm::front::state<> { };
using initial_state = InitState;
// clang-format off
struct transition_table : mpl::vector<
Row < InitState, none, SubSM >
> {};
// clang-format on
};
class mainSM : public msm::back::state_machine<mainSMFE> {
public:
mainSM()
: msm::back::state_machine<mainSMFE>(
msm::back::states_ << SubSM(sb)) {};
};
int main() {
mainSM sm;
}
版画
SubSMFE constructor