Controllo Eredità con i template in C++
Domanda
Ho una classe che è una classe wrapper(serve come interfaccia comune) intorno ad un'altra classe che implementa le funzionalità richieste.Quindi il mio codice simile a questo.
template<typename ImplemenationClass> class WrapperClass {
// the code goes here
}
Ora, come faccio a verificare che ImplementationClass
può essere derivata da un insieme di classi solo, simile a java generics
<? extends BaseClass>
sintassi?
Soluzione
E ' verboso, ma si può fare così:
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_base_of.hpp>
struct base {};
template <typename ImplementationClass, class Enable = void>
class WrapperClass;
template <typename ImplementationClass>
class WrapperClass<ImplementationClass,
typename boost::enable_if<
boost::is_base_of<base,ImplementationClass> >::type>
{};
struct derived : base {};
struct not_derived {};
int main() {
WrapperClass<derived> x;
// Compile error here:
WrapperClass<not_derived> y;
}
Questo richiede un compilatore con un buon supporto per lo standard più recente, i compilatori devono essere belle, ma le vecchie versioni di Visual C++ non essere).Per ulteriori informazioni, vedere la Boost.Enable_If documentazione.
Come ha detto Ferruccio, una più semplice, ma meno potente di attuazione:
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_base_of.hpp>
struct base {};
template <typename ImplementationClass>
class WrapperClass
{
BOOST_STATIC_ASSERT((
boost::is_base_of<base, ImplementationClass>::value));
};
Altri suggerimenti
Allo stato attuale delle cose, non c'è altro modo che commenti o una soluzione di terze parti.Boost fornisce un concetto di controllo library per questo, e penso che il gcc ha anche un'implementazione.I concetti sono sulla lista di C++0x miglioramenti, ma non sono sicuro se è possibile specificare sottotipi - sono più per il "deve supportare queste operazioni", che è (circa) equivalente.
Edit: Wikipedia è questo sezione concetti in C++0x, che è significativamente più facile da leggere rispetto ad elaborare proposte.
Vedere Stoustrup parole sull'argomento.
Fondamentalmente una piccola classe di, che si crea un'istanza da qualche parte, ad es.l'europa e l'america latina classi costruttore.
template<class T, class B> struct Derived_from {
static void constraints(T* p) { B* pb = p; }
Derived_from() { void(*p)(T*) = constraints; }
};