2012-06-20 11 views
6

Wenn alle Typen in meinem boost::variant die gleiche Methode unterstützen, gibt es eine Möglichkeit, es generisch aufzurufen (d. H. Nicht separat für jede Methode der static_visitor aufrufen)?Calling Methoden gemeinsamen Typen in einem boost :: variant

Ich versuche, etwas zu erhalten zu arbeiten:

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(); 
} 

aber es funktioniert nicht sagen 'boo' : is not a member of 'boost::variant<T0_,T1,T2>' zu kompilieren.

Derzeit habe ich einige Klassen alle von einer Schnittstelle erben, so dass ihre einzige gemeinsame Methode polymorph verwendet werden kann. Ich möchte auch in der Lage sein, die Klassen über einen Besucher zu verwenden, da alle anderen Methoden für jede konkrete Klasse einzigartig sind. Ich habe gehofft, könnte eine bessere Alternative zur Implementierung meines eigenen Besuchermechanismus hier sein. Ist es?

Antwort

4

Es gibt keinen direkten Weg, aber Sie können den static_visitor mit Templating ziemlich präzise gestalten.

aus den Boost-docs Modifiziert:

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

Jetzt können Sie dies tun:

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

Infact Sie dies einen Funktionszeiger Ihrer Basisklasse nehmen verallgemeinern kann:

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

Dann können Sie tun:

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

Oder so ähnlich - ich habe wahrscheinlich meine Funktion Zeiger-Syntax falsch, aber hoffentlich bekommen Sie die Idee.

Verwandte Themen