Boost logo

Boost :

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://lists.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


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk