2013-11-28 24 views
5

vorrei scrivere nel mio programma C++ qualcosa di simile:C++ Classe eredità e modelli

class A { 
public: 
    void a(); 
} 

template <class B extends A> 
class C { 
B instance; 
} 

è possibile? In altre parole: C++ mi consente di dire che la classe all'interno di un modello è una sottoclasse di qualcos'altro?

+0

@LuchianGrigore: simile, ma quello riguarda le funzioni e questo riguarda le classi. Le soluzioni possono essere leggermente diverse (ad es. Enable_if è la risposta migliore, ma qui non ha molto senso). –

risposta

4

Non proprio in modo diretto. Ma è possibile utilizzare static_assert con type_traits, in questo modo:

static_assert(is_base_of<A,B>::value, "C<B> requires B:A"); 

Si può mettere che nel costruttore per esempio, allora non riuscirà a compilare se il requisito non è soddisfatto. Nota che questa è tutta roba C++ 11, ma esiste in Boost molto tempo prima, oppure puoi codificarti da solo se sei veramente bloccato (non richiede il supporto della lingua).

5

Definire una meta-funzione chiamata extends (che è solo un nome rivestite di zucchero) come:

template<typename D, typename B> 
using extends = std::is_base_of<B,D>; 

Quindi definire la classe come:

template <class B> 
class C 
{ 
    //here you can check it, and generate your own error message! 
    static_assert(extends<B,A>(), 
       "Constraint Violation: B doesn't derive from A."); 

    B instance; 
}; 

alternativa, è possibile scrivere questo posto :

//define it a bit differently now! 
template<typename D, typename B> 
using extends = typename std::enable_if<std::is_base_of<B,D>::value>::type; 

template <class B, class Unused=extends<B,A>> 
class C 
{ 
     B instance; 
}; 

Ma in questo caso, non si dispone di opportunità di generare il proprio erro messaggio. Il compilatore è libero di inviare a qualsiasi messaggio di errore che potrebbe essere difficile da comprendere.

In ogni caso, probabilmente ti rendi conto che puoi utilizzare direttamente std::is_base_of<>. Ma se stai cercando il nome ricoperto di zucchero, allora extends suona bene!

+0

è possibile rimuovere 'Unused' dal secondo esempio –