c++ - Transform a list of pointers to base class -


i have design have std::list of base pointers i'd transform parallel list adds behavior. problem i'm having object i'm trying use transform doesnt know actual types when invoked.

it's quite possible i'm missing subtle , there easy fix. however, if design flaw (i've seen suggested in other posts) appropriate way approach this?

suppose following:

class sprite { /* ... */ }; class character : public sprite {}; class markup : public sprite {}; 

these constructed (based on input) std::list< sprite * >. i'd take list , transform parallel structure suitable output operations. instance, given:

class htmlsprite { /* ... */ }; class htmlcharacter : public htmlsprite {}; class htmlmarkup : public htmlsprite {}; 

i'd ideally like

std::transform(sprites.begin (), sprites.end (), html.begin (), htmlconvert); 

with like

struct htmlconvert_ {   htmlsprite * operator () (const character * c) { return new htmlcharacter (); }   htmlsprite * operator () (const markup * c) { return new htmlmarkup (); } } htmlconvert; 

now, error

call of `(htmlconvert) (const sprite* const&)' ambiguous htmlsprite* htmlconvert::operator()(const character*) const <near match> 

which leads me question. best solution problem - redesign or otherwise?

thanks.

in addition joshd's suggestion, can keep door open other transformations using visitor pattern.

add method dispatch_visit sprite hierarchy, using covariant return types:

class sprite{     virtual htmlsprite * dispatch_visit( htmlconvert_ const &c ) const = 0; }; class character : public sprite {     virtual htmlcharacter * dispatch_visit( htmlconvert_ const &c ) const         { return c( ); } }; class markup : public sprite {     virtual htmlmarkup * dispatch_visit( htmlconvert_ const &c ) const         { return c( ); } }; 

this allows each object notify converter of dynamic type — essentially, dynamic dispatch parallel type, or parallel type hierarchy. else pretty works code written… best candidate chosen among operator()() functions of converter, based on static parameter type.

oh, you'll need add "missing function" converter:

struct htmlconvert_ {   htmlsprite * operator () (const sprite * c) { return c->dispatch_visit( *this ); }   htmlcharacter * operator () (const character * c) { return new htmlcharacter (); }   htmlmarkup * operator () (const markup * c) { return new htmlmarkup (); } } htmlconvert; 

hmm, repetitive function encapsulated template… seems work in c++0x if want visitable template automatically determine return type of dispatch_visit. if don't principal_base can factor out.

#include <functional>  template< class t > struct principal_base     { typedef void type; };  template< class client, class visitor,     class base = typename principal_base< client >::type > struct visitable :     virtual visitable< typename principal_base< client >::type, visitor > {     virtual typename std::result_of< visitor( client * ) >::type     dispatch_visit( visitor const &v ) const         { return v( static_cast< client const * >( ) ); } };  template< class client, class visitor > struct visitable< client, visitor, void > {     virtual typename std::result_of< visitor( client * ) >::type     dispatch_visit( visitor const &v ) const = 0; };  class htmlsprite { /* ... */ }; class htmlcharacter : public htmlsprite {}; class htmlmarkup : public htmlsprite {};  class sprite; class character; class markup;  struct htmlconvert_ {   htmlsprite * operator () (const sprite * c);   htmlcharacter * operator () (const character * c);   htmlmarkup * operator () (const markup * c); } htmlconvert;  class sprite : public visitable< sprite, htmlconvert_ > {}; template<> struct principal_base< character >     { typedef sprite type; }; class character : public sprite, visitable< character, htmlconvert_ > {}; template<> struct principal_base< markup >     { typedef sprite type; }; class markup : public sprite, visitable< markup, htmlconvert_ > {};  //class invalid : character, markup {};  htmlsprite * htmlconvert_::operator () (const sprite * c)     { return c->dispatch_visit( *this ); } htmlcharacter * htmlconvert_::operator () (const character * c)     { return new htmlcharacter (); } htmlmarkup * htmlconvert_::operator () (const markup * c)     { return new htmlmarkup (); } 

Comments

Popular posts from this blog

ASP.NET/SQL find the element ID and update database -

jquery - appear modal windows bottom -

c++ - Compiling static TagLib 1.6.3 libraries for Windows -