2017-07-16 1 views
2

sagen, dass ich einige Template-Klassen haben:Wie kann festgestellt werden, ob ein Typ zur Kompilierungszeit von einer Vorlagenklasse abgeleitet wird?

template<class T> 
class Foo{} 

template<class T> 
class Bar{} 

Nun, ich möchte sicherstellen (zum Zeitpunkt der Kompilierung), dass die in Bar verwendete Art von Foo abgeleitet wird. Ich habe bereits this Antwort gefunden, die zeigt, wie man es zur Laufzeit macht, aber ich würde gerne zur Kompilierzeit überprüfen, vielleicht mit static_assert oder etwas.
Gibt es eine Möglichkeit, dies zu tun?

+1

Es könnte einige [type-traits] (http://en.cppreference.com/w/cpp/types#Type_traits_.28since_C.2B.2B11.29) geben, die Sie verwenden könnten. –

+1

@Someprogrammerdude Ja, ich habe ein bisschen nachgeschaut. is_base_of funktioniert vielleicht, aber ich weiß nur, wie ich es verwenden kann, wenn Foo eine normale Klasse und keine Template-Klasse ist. – Mastrem

Antwort

6

Nun möchte ich sicherstellen (bei Compiletime), dass der in Bar verwendete Typ von Foo abgeleitet ist.

Sie können etwas tun:

#include<type_traits> 
#include<utility> 

template<class T> 
class Foo{}; 

template<typename T> 
std::true_type test(const Foo<T> &); 

std::false_type test(...); 

template<class T> 
class Bar { 
    static_assert(decltype(test(std::declval<T>()))::value, "!"); 
}; 

struct S: Foo<int> {}; 

int main() { 
    Bar<S> ok1; 
    Bar<Foo<int>> ok2; 
    // Bar<int> ko; 
} 

es auf wandbox See.
Die Grundidee ist, dass Sie ein temporäres vom Typ T an const Foo<U> & binden können, wenn T von einer Spezialisierung Foo abgeleitet ist, egal was U ist. Daher können Sie eine Reihe von Funktionen wie die im Beispiel zum Testen deklarieren (keine Definition erforderlich) und dann den deklarierten Rückgabetyp in einem static_assert oder einem anderen konstanten Kontext verwenden.


bearbeiten

Wie in den Kommentaren von @Quentin vorgeschlagen, ist es wahrscheinlich lohnt sich die Referenz mit einem Zeiger ersetzt Fehlalarme aus der Umwandlung Errichter und Betreiber zu verhindern.

+4

Dies überprüft genau Foo, OP wollen Subtyp von Foo. –

+0

@yurikilochek Richtig. Es wurde korrigiert, um abgeleitete Klassen zu finden. – skypjack

+0

Ich würde die Referenz durch einen Zeiger ersetzen, um falsche Positive von Konvertierungskonstruktoren und Operatoren zu verhindern. – Quentin

Verwandte Themen