Dear Boost experts, I'm trying to find a solution to the following problem. I'm iterating over an MPL sequence and once I found the appropriate type in the sequence I call a static function that returns a pointer to a newly created object that I need to return to the caller of the ModelDispatcher::parse member function with its exact type. In other words I need to propagate the exact type of the object created somewhere in a recursive chain of function calls back to the original caller. Unfortunately I can't figure out how to specify the return type of this recursive function. Every type in the sequence has the following form: struct sequence_item { typedef the_real_type type ; static the_real_type *parse( const QDomElement & ) ; } ; The code for iterating over the sequence is the following: template < typename It, typename End > ?? *dispatchM( const QDomElement &, mpl::true_ /* endofvec */ ) { return 0 ; } template < typename It, typename End > ?? *dispatchM( const QDomElement &element, mpl::false_ ) { typedef typename mpl::deref< It >::type MapEntry ; if ( element.tagName() == MapEntry::first::name() ) { // return type is MapEntry::second::type return MapEntry::second::parse( element ) ; } else { typedef typename mpl::next< It >::type Next ; return dispatchM< Next, End >( element, typename boost::is_same< Next, End >::type() ) ; } } template < typename ModelMap > struct ModelDispatcher { static ?? *parse( const QDomElement &element ) { mpl::false_ f ; return dispatchM< typename mpl::begin< ModelMap >::type, typename mpl::end< ModelMap >::type >( element, f ) ; } } ; Thanks a lot for your help. Istvan
Every type in the sequence has the following form:
struct sequence_item { typedef the_real_type type ; static the_real_type *parse( const QDomElement & ) ; } ;
The code for iterating over the sequence is the following:
template < typename It, typename End > ?? *dispatchM( const QDomElement &, mpl::true_ /* endofvec */ ) { return 0 ; }
template < typename It, typename End > ?? *dispatchM( const QDomElement &element, mpl::false_ ) { typedef typename mpl::deref< It >::type MapEntry ; if ( element.tagName() == MapEntry::first::name() )
The above line means that you figure out the correct type in *run-time*, don't you? But the result type must be known in compile-time.
on Mon Oct 10 2011, Igor R
Every type in the sequence has the following form:
struct sequence_item { typedef the_real_type type ; static the_real_type *parse( const QDomElement & ) ; } ;
The code for iterating over the sequence is the following:
template < typename It, typename End > ?? *dispatchM( const QDomElement &, mpl::true_ /* endofvec */ ) { return 0 ; }
template < typename It, typename End > ?? *dispatchM( const QDomElement &element, mpl::false_ ) { typedef typename mpl::deref< It >::type MapEntry ; if ( element.tagName() == MapEntry::first::name() )
The above line means that you figure out the correct type in *run-time*, don't you? But the result type must be known in compile-time.
Yeah, as long as you're doing that with a runtime test, your only option is to use some kind of type erasure (boost::any, polymorphic base class, etc). If you are stuck with a runtime test, you might consider passing in a function object to handle whatever was going to be done at the outer level with full knowledge of the types. -- Dave Abrahams BoostPro Computing http://www.boostpro.com
on Mon Oct 10 2011, Igor R
Yeah, as long as you're doing that with a runtime test, your only option is to use some kind of type erasure (boost::any, polymorphic base class, etc).
Or Boost.Variant.
(which is what I meant by etc.) I think if you are going to use type erasure, Igor's suggestion is probably the approach most suited to a metaprogrammed system. -- Dave Abrahams BoostPro Computing http://www.boostpro.com
On Mon, Oct 10, 2011 at 11:49 PM, Dave Abrahams
on Mon Oct 10 2011, Igor R
wrote: Yeah, as long as you're doing that with a runtime test, your only option is to use some kind of type erasure (boost::any, polymorphic base class, etc).
Or Boost.Variant.
(which is what I meant by etc.)
I think if you are going to use type erasure, Igor's suggestion is probably the approach most suited to a metaprogrammed system.
Thank you for your suggestions. It seems that one way or the other I'll have to bite the bullet and use (at least partially) a more traditional approach in my application. It all started when I saw that to avoid duplicating information among my classes I created a complex inheritance hierarchy. I didn't like it and I decided to try using some generative programming techniques to build my classes at compile-time. So far so good but then I was facing all kind of other problems like how to store these heterogeneous objects in containers or, like in the example above, mix run-time and compile-time tests...
on Tue Oct 11 2011, Istvan Buki
Thank you for your suggestions.
It seems that one way or the other I'll have to bite the bullet and use (at least partially) a more traditional approach in my application. It all started when I saw that to avoid duplicating information among my classes I created a complex inheritance hierarchy. I didn't like it and I decided to try using some generative programming techniques to build my classes at compile-time. So far so good but then I was facing all kind of other problems like how to store these heterogeneous objects in containers or, like in the example above, mix run-time and compile-time tests...
Well, boost::variant is very well-suited to these problems. -- Dave Abrahams BoostPro Computing http://www.boostpro.com
participants (3)
-
Dave Abrahams
-
Igor R
-
Istvan Buki