2011-04-21 12 views
6

Mi chiedo se ci sia un modo per limitare la generazione di codice per un modello usando condizioni personalizzate nel mio caso voglio funzionare foo per essere chiamato solo se template class T ha ereditato dalla classe bar (qualcosa come questo)restrizione classe modello

template <class T:public bar> void foo() 
{ 
    // do something 
} 
+3

Si potrebbe essere in grado di utilizzare Boost 'enable_if'. –

+0

Se hai a che fare con l'ereditarietà pubblica, allora c'è un altro modo. Vedi la mia risposta. – iammilind

risposta

9

è possibile limitare T pur usando "Sostituzione il fallimento non è un errore" (SFINAE):

template <typename T> 
typename std::enable_if<std::is_base_of<bar, T>::value>::type foo() 
{ 

} 

Se T non deriva da bar, la specializzazione del modello di funzione fallirà e non sarà considerato durante la risoluzione di sovraccarico. std::enable_if e std::is_base_of sono nuovi componenti della libreria standard C++ aggiunti nella prossima revisione, C++ 0x. Se l'implementazione del compilatore/libreria standard non li supporta ancora, puoi trovarli anche in C++ TR1 o Boost.TypeTraits.

+0

Infatti, o se la tua libreria 'std' non ha' is_base_of', è in Boost. –

+0

Sì. L'equivalente Boost sarebbe 'boost :: enable_if > :: type'; lo 'std :: enable_if' prende un' bool' come primo argomento mentre 'boost :: enable_if' accetta un tipo. 'std :: enable_if' è equivalente a' boost :: enable_if_c'. –

+0

avete idea di come la stessa libreria std abbia implementato le classi enable_if o is_base_of? – Ali1S232

0

Sì, è possibile utilizzare la seguente tecnica (per ereditarietà pubblica). Provocherebbe un sovraccarico di una sola inizializzazione del puntatore.

Edit: Re-writing

template<typename Parent, typename Child> 
struct IsParentChild 
{ 
    static Parent* Check (Child *p) { return p; } 
    Parent* (*t_)(Child*); 
    IsParentChild() : t_(&Check) {} // function instantiation only 
}; 

template<typename T> 
void foo() 
{ 
    IsParentChild<Bar, T> check; 
// ... 
}