2012-06-20 37 views
6

Jeśli wszystkie typy w moim boost::variant wspierania tej samej metody, czy istnieje sposób, aby nazwać ogólnie (tzn nie nazywając ją oddzielnie dla każdego sposobu static_visitor)?Wywoływanie metody wspólne dla typów w boost :: variant

Próbuję uzyskać coś podobnego do pracy:

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

ale nie udaje mu się skompilować mówiąc 'boo' : is not a member of 'boost::variant<T0_,T1,T2>'.

Obecnie niektóre klasy dziedziczą z interfejsu, dzięki czemu ich pojedyncza wspólna metoda może być używana polimorficznie. Chcę również móc korzystać z klas przez odwiedzającego, ponieważ wszystkie inne metody są unikalne dla każdej konkretnej klasy. Miałem nadzieję, że boost::variant może być lepszą alternatywą dla implementacji mojego mechanizmu odwiedzającego tutaj. Czy to jest?

Odpowiedz

4

Nie ma bezpośredniej drogi, ale możesz sprawić, że static_visitor będzie dość zwięzły za pomocą szablonów.

Modified od docs doładowania:

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

Teraz można to zrobić:

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

Rzeczywiście można uogólniać tego podjąć wskaźnik funkcji klasy bazowej:

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

Następnie możesz wykonać:

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

Albo coś w tym stylu - prawdopodobnie mam błędną składnię wskaźnika funkcji, ale mam nadzieję, że wpadłeś na ten pomysł.