2012-06-20 7 views
6

Se tutti i tipi nel mio boost::variant supportano lo stesso metodo, esiste un modo per chiamarlo genericamente (cioè non chiamarlo separatamente per ogni metodo dello static_visitor)?Chiamare metodi comuni ai tipi in un boost :: variante

Sto cercando di ottenere qualcosa di simile al lavoro:

class A 
{ 
    void boo() {} 
}; 

class B 
{ 
    void boo() {} 
}; 

class C 
{ 
    void boo() {} 
}; 

typedef boost::variant<A, B, C> X; 

void foo(X& d) 
{ 
    x.boo(); 
} 

ma non riesce a compilare dicendo 'boo' : is not a member of 'boost::variant<T0_,T1,T2>'.

Attualmente, ho alcune classi tutte ereditate da un'interfaccia in modo che il loro singolo metodo condiviso possa essere utilizzato polimorficamente. Voglio anche essere in grado di utilizzare le classi tramite un visitatore in quanto tutti gli altri metodi sono unici per ogni classe concreta. Speravo che boost::variant potesse essere un'alternativa migliore all'implementazione del mio meccanismo di visitatore qui. È?

risposta

4

Non c'è un modo diretto, ma è possibile rendere statico il moderatore abbastanza conciso usando i modelli.

modificati rispetto alla documentazione di spinta:

struct boo_generic : public boost::static_visitor<> 
{ 
    template <typename T> 
    void operator()(T & operand) const 
    { 
     operand.boo(); 
    } 
}; 

Ora si può fare questo:

boost::apply_visitor(boo_generic(), v); 

Infatti si può generalizzare questo per prendere un puntatore a funzione della classe di base:

struct fn_generic : public boost::static_visitor<> 
{ 
    fn_generic(void (IBase::fn)()) : fn_(fn) {} 
    template<T> void operator() (T & op) const { op.*fn(); } 
} 

Quindi puoi fare:

boost::apply_visitor(boo_generic(IBase::boo), v); 

O qualcosa del genere: probabilmente ho sbagliato la sintassi del mio puntatore di funzione, ma spero che tu abbia capito l'idea.

Problemi correlati