2013-11-28 11 views
5

Ich mag würde in meinem C++ Programm so etwas wie schreiben:C++ Klassenvererbung und Vorlagen

class A { 
public: 
    void a(); 
} 

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

Ist das möglich? Mit anderen Worten: lässt C++ zu, dass die Klasse innerhalb einer Vorlage eine Unterklasse von etwas anderem ist?

+0

@LuchianGrigore: ähnlich, aber das ist über Funktionen und das ist über Klassen. Die Lösungen können leicht unterschiedlich sein (z. B. enable_if ist die beste Antwort dort, macht aber hier nicht so viel Sinn). –

Antwort

4

Nicht wirklich auf direkte Weise. Aber Sie können static_assert mit type_traits verwenden, wie folgt aus:

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

Sie können das zum Beispiel in Ihrem Konstruktor setzen, dann wird es nicht kompiliert, wenn die Anforderung nicht erfüllt ist. Beachten Sie, dass dies alles C++ 11 Zeug ist, aber es existiert lange vorher in Boost, oder Sie können es selbst codieren, wenn Sie wirklich festhängen (es erfordert keine Sprachunterstützung).

5

Definieren Sie eine Meta-Funktion namens extends (die nur ein zuckerbeschichteten Name ist) als:

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

dann Ihre Klasse definieren als:

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

Oder Sie können diese schreiben statt :

//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; 
}; 

Aber in diesem Fall haben Sie keine Möglichkeit, Ihre eigenen Fehler zu generieren r Nachricht. Der Compiler ist frei jede Fehlermeldung bei Ihnen zu werfen, die schwer zu verstehen sein kann.

Wie auch immer, Sie wahrscheinlich wissen, dass Sie std::is_base_of<> direkt verwenden können. Aber wenn Sie nach Zucker überzogenen Name suchen, dann extends hört sich gut an!

+0

können Sie 'Unused' aus dem 2. Beispiel entfernen –