I expect the reference to stateMachineInstance to be used as the dependency whenever it is required.
This includes any internal dependency that boost::sml might have on an instance of StateMachine and also for the parameter of the lambda expression.
Also, the behavior is unexpected, because any modifications of the object, passed in as the reference, is not actually considered by the state machine. This is because boost::sml::sm uses it's internal copy of StateMachine instead of the reference passed in.
An example of this is when using a lambda expression that captures [this](){...} e.g. as an action like so:
This would allow the boost::sml::sm to be a member of a class, that subclasses StateMachine.
class ClassWithStateMachine final : StateMachine {
boost::sml::sm<StateMachine> sm{
static_cast<StateMachine&>(*this)
};
Doing it this way, it greatly improves the usability in an object oriented context, e.g. when only ClassWithStateMachine should be able to access protected variables of StateMachine or for testing.
Actual Behavior
boost::sml is internally trying to make a copy of StateMachine from the reference StateMachine &, which fails because the copy constructor is deleted.
The error message is the following:
In file included from /home/seb/code/example_use_boost_sml_in_class/main2.cpp:1:
/home/seb/code/example_use_boost_sml_in_class/external/sml/include/boost/sml.hpp:447:23: error: call to deleted constructor of '(anonymous namespace)::StateMachine'
: pool_type<Ts>(try_get<aux::remove_const_t<aux::remove_reference_t<aux::remove_pointer_t<Ts>>>>(&p))... {}
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/seb/code/example_use_boost_sml_in_class/external/sml/include/boost/sml.hpp:1755:41: note: in instantiation of function template specialization 'boost::sml::aux::pool<(anonymous namespace)::StateMachine>::pool<(anonymous namespace)::StateMachine &>' requested here
constexpr explicit sm(TDeps &&deps) : deps_{aux::init{}, aux::pool<TDeps>{deps}}, sub_sms_{aux::pool<TDeps>{deps}} {
^
/home/seb/code/example_use_boost_sml_in_class/main2.cpp:26:27: note: in instantiation of function template specialization 'boost::sml::back::sm<boost::sml::back::sm_policy<(anonymous namespace)::StateMachine>>::sm<(anonymous namespace)::StateMachine &, 0>' requested here
sml::sm<StateMachine> sm{
^
/home/seb/code/example_use_boost_sml_in_class/main2.cpp:11:9: note: 'StateMachine' has been explicitly marked deleted here
StateMachine(const StateMachine &) = delete;
^
/home/seb/code/example_use_boost_sml_in_class/external/sml/include/boost/sml.hpp:361:39: note: passing argument to parameter 'object' here
constexpr explicit pool_type_impl(T object) : value{object} {}
^
/home/seb/code/example_use_boost_sml_in_class/external/sml/include/boost/sml.hpp:1421:56: error: call to deleted constructor of 'aux::conditional_t<aux::is_empty<typename sm_policy<StateMachine>::sm>::value, aux::none_type, typename sm_policy<StateMachine>::sm>' (aka '(anonymous namespace)::StateMachine')
constexpr sm_impl(const TPool &p, aux::false_type) : sm_t{aux::try_get<sm_t>(&p)}, transitions_{(*this)()} {
^ ~~~~~~~~~~~~~~~~~~~~~~~~
/home/seb/code/example_use_boost_sml_in_class/external/sml/include/boost/sml.hpp:1419:50: note: in instantiation of function template specialization 'boost::sml::back::sm_impl<boost::sml::back::sm_policy<(anonymous namespace)::StateMachine>>::sm_impl<boost::sml::aux::pool<(anonymous namespace)::StateMachine &>>' requested here
constexpr sm_impl(aux::init, const TPool &p) : sm_impl{p, aux::is_empty<sm_t>{}} {}
^
/home/seb/code/example_use_boost_sml_in_class/external/sml/include/boost/sml.hpp:363:54: note: in instantiation of function template specialization 'boost::sml::back::sm_impl<boost::sml::back::sm_policy<(anonymous namespace)::StateMachine>>::sm_impl<boost::sml::aux::pool<(anonymous namespace)::StateMachine &>>' requested here
constexpr pool_type_impl(init i, TObject object) : value{i, object} {}
^
/home/seb/code/example_use_boost_sml_in_class/external/sml/include/boost/sml.hpp:449:45: note: in instantiation of function template specialization 'boost::sml::aux::pool_type_impl<boost::sml::back::sm_impl<boost::sml::back::sm_policy<(anonymous namespace)::StateMachine>>>::pool_type_impl<boost::sml::aux::pool<(anonymous namespace)::StateMachine &>>' requested here
constexpr pool(const pool<TArgs...> &p) : pool_type<Ts>(init{}, p)... {}
^
/home/seb/code/example_use_boost_sml_in_class/external/sml/include/boost/sml.hpp:1755:85: note: in instantiation of function template specialization 'boost::sml::aux::pool<boost::sml::back::sm_impl<boost::sml::back::sm_policy<(anonymous namespace)::StateMachine>>>::pool<(anonymous namespace)::StateMachine &>' requested here
constexpr explicit sm(TDeps &&deps) : deps_{aux::init{}, aux::pool<TDeps>{deps}}, sub_sms_{aux::pool<TDeps>{deps}} {
^
/home/seb/code/example_use_boost_sml_in_class/main2.cpp:26:27: note: in instantiation of function template specialization 'boost::sml::back::sm<boost::sml::back::sm_policy<(anonymous namespace)::StateMachine>>::sm<(anonymous namespace)::StateMachine &, 0>' requested here
sml::sm<StateMachine> sm{
^
/home/seb/code/example_use_boost_sml_in_class/main2.cpp:11:9: note: 'StateMachine' has been explicitly marked deleted here
StateMachine(const StateMachine &) = delete;
^
Steps to Reproduce the Problem
Compile the source code above with boost::sml v1.1.9
Expected Behavior
Given this code:
I expect the reference to
stateMachineInstance
to be used as the dependency whenever it is required. This includes any internal dependency that boost::sml might have on an instance ofStateMachine
and also for the parameter of the lambda expression.Also, the behavior is unexpected, because any modifications of the object, passed in as the reference, is not actually considered by the state machine. This is because
boost::sml::sm
uses it's internal copy ofStateMachine
instead of the reference passed in.An example of this is when using a lambda expression that captures
[this](){...}
e.g. as an action like so:Why do I also want this behavior?
This would allow the
boost::sml::sm
to be a member of a class, that subclassesStateMachine
.Doing it this way, it greatly improves the usability in an object oriented context, e.g. when only
ClassWithStateMachine
should be able to access protected variables ofStateMachine
or for testing.Actual Behavior
boost::sml is internally trying to make a copy of
StateMachine
from the referenceStateMachine &
, which fails because the copy constructor is deleted.The error message is the following:
Steps to Reproduce the Problem
Compile the source code above with boost::sml v1.1.9
Specifications