$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
Subject: Re: [boost] [msm]Event convert at exit point
From: Christophe Henry (christophe.j.henry_at_[hidden])
Date: 2011-10-17 17:08:47
----- Original Message -----
From: "Takatoshi Kondo" <redboltz_at_[hidden]>
Newsgroups: gmane.comp.lib.boost.devel
To: <boost_at_[hidden]>
Sent: Wednesday, October 12, 2011 3:39 PM
Subject: Re: [msm]Event convert at exit point
> Hi Christophe,
>
>>> Hi Takatoshi,
>>>
>>> this question has already been asked some time ago in a slightly
>>> different
>>> context (http://listarchives.boost.org/Archives/boost/2010/09/170506.php). This
>>> is
>>> unfortunately one of the points where I had to leave the compile-time
>>> world
>>> earlier than I would like (but found no better solution yet). While
>>> Event1
>>> will not be considered for forwarding, the compiler does not know
>>> because
>>> it's only known at run-time, and it therefore complains that you cannot
>>> create Event1 from Event2.
>>>
>>> The surprise to me is that the compiler is happy with only your second
>>> constructor, I'd expect it to require a constructor taking Event1.
>>> Should it
>>> happen, you will need to use the enable_if / disable_if workaround
>>> presented
>>> in the above thread.
>>>
>>> I'll update the doc so that this current limitation is documented until
>>> I
>>> find a better solution.
>
> Thanks for the reply. I understood current situation.
>
>> Or simplier:
>>
>> template <class T> Event3(T const& ):val(0) {} // not used
>> Event3(Event2 const& e):val(e.val) {} //conversion constructor
>
> Correct. It works well.
> In my usecase, I think it's typical, the outer event(Event3) shouldn't
> know about
> inner event(Event2). In other words, outer event is an interface of a
> sub state machine.
>
> When I use the SFINAE solution, the predicate is important.
> If I choose the is_same, it still needs inner event information.
> template <class T> OuterEvent(T const& t, typename
> enable_if<is_same<T, InnerEvent> >::type* = 0);
>
> I considered some approaches.
> The first approach is the InnerEvent inherits the OuterEvent and use
> the is_base_of.
>
> struct InnerEvent:OuterEvent {};
> is_base_of<T, OuterEvent>
>
> And next, I realized that if the InnerEvent inherits the OuterEvent,
> we can construct
> the OuterEvent from the InnerEvent automatically. It is the slicing.
> In my usecase,
> I think it works well.
>
> struct OuterEvent {
> int val;
> };
> struct InnerEvent:OuterEvent {};
> struct Exit:msm::front::exit_pseudo_state<OuterEvent> {};
> // Start Event Next Action Guard
> msmf::Row < SubState1, InnerEvent, Exit, msmf::none, msmf::none >
>
> Regards,
> Takatoshi
Hi Takatoshi,
you can also use SFINAE without having Event3 know anything about Event2,
just don't use is_same but a tag inside Event2.
struct Event2
{
typedef int inner_event;
};
BOOST_MPL_HAS_XXX_TRAIT_DEF(inner_event)
you can now write:
typename enable_if<has_inner_event<T> >::type ...
This way, Event3 does not know Event2 but a "property" of a set of events.
Granted, this is not incredibly beautiful but it does the job.
Regards,
Christophe