Template Spezialisierung für eine bestimmte template Klasse als Argument ...
-
Hallo ...

template<const unsigned N, typename T> class array { //sth. cool here }; template<typename T> class test { }; /* Spezialisierung für template<typename T> class test wenn * template<const unsigned N, typename T> class array und ALLE ALLE ALLE * Ableitungen davon als Argument anagegeben */ template<> class test< template<const unsigned N, typename T> class array > { };Leider Gottes sieht gcc das bisschen anders:
Fehler: Templateargument 1 ist ungültig
expected unqualified-id before »>« token
Fehler: »array« ist kein Template-Typ
...
...
...
...
-
template<const unsigned N, typename T> class array { //sth. cool here }; class arrayDeri : public array<3,float> { }; template<typename T> struct test { test() { cout << "Ich habe " << typeid(T).name() << " als Argument!" << endl; } }; template<> template<const unsigned N, typename T> struct test< class array<N,T> > { test() { cout << "Ich habe array<" << N << "," << typeid(T).name() << "> als Argument!" << endl; } }; int main() { test<float> t1; test< array<3,float> > t2; test< arrayDeri > t3;So ist es richtig!
Ich habe f als Argument!
Ich habe array<3,f> als Argument!
Ich habe 9arrayDeri als Argument!Jedoch landet arrayDeri wohl nicht in der Spezialisierung!! Was tun? :schland:

-
Das geht nicht. Eine Ableitung als Argument wird niemals die Spezialisierung der Basisklasse Instazieren!
-
KlUgScHeIsSeR schrieb:
Das geht nicht. Eine Ableitung als Argument wird niemals die Spezialisierung der Basisklasse Instazieren!
Ja du Klugscheisser
Hab ich gemerkt. Jedoch muss es doch alternativen geben ohne einen neuen Klassentyp zu erstellen ...!?
-
Pigeon schrieb:
KlUgScHeIsSeR schrieb:
Das geht nicht. Eine Ableitung als Argument wird niemals die Spezialisierung der Basisklasse Instazieren!
Ja du Klugscheisser
Hab ich gemerkt. Jedoch muss es doch alternativen geben ohne einen neuen Klassentyp zu erstellen ...!?Es gibt Alternativen, allerdings keine, die exakt das machen, was du andeutest.
class foo : public array<10,int>, public array<100,float> { ... }; test<foo> // welche N und T soll hier deduziert werden?Man kann zwar ermitteln, ob eine gegebene Klasse von einer anderen abgeleitet ist, aber es existiert kein Mechanismus, um für eine gegebene Klasse alle Basisklassen systematisch aufzuzählen.
-
Den Fall habe ich nicht bedacht (da das mehrfache erben eigendlich nicht vorgesehen ist ...). Was wären denn die besagten Alternativen?

-
Also meine template-Klasse die array als Argument nehmen soll ist nicht für Typen die mehrfach von array geerbt haben zu gebrauchen. Also sind die neuen Bedingungen, dass der Typ 1x von array geerbt hat. Ansonsten ist es ein Fall für das allgemeine template<typename T> class test
Aber ich fürchte schon sowas ist auch nicht zu machen, ne?

-
Mit einer einfachen Spezialisierung von test kommen wir nicht weiter. Was wir hier brauchen, ist eine Templatemetafunktion, die durch ein geeignetes Prädikat eine Spezialisierung des richtigen Templates auswählt.
template<typename T> struct test; // Template für den Fall, dass T nicht von array<..> abgeleitet ist, ohne direkt darauf Bezug zu nehmen (static_asserts innerhalb der Klasse sind natürlich möglich template<typename T> struct test_of_array; // ditto, für Ableitung von array<..> template<typename T> struct test_of { typedef typename if_< magical_predicate<T>, test<T>, test_of_array<T> >::type type; };Das Problem ist jetzt, wie magical_predicate zu schreiben ist. Einfach für entsprechende T zu spezialisieren würde wieder zum ursprünglichen Problem führen.
Eine Möglichkeit wäre, eine hinreichend umfängliche aber beschränkte Menge von array-Spezialisierungen so zu durchsuchen, dass ein Exemplar gefunden werden kann, dass Basisklasse ist. Angemessenen Compilerungszeiten dürfte das allerdings nicht zuträglich sein. Eleganter wäre evtl. Alle array-Spezialisierungen von einer speziellen Klasse, die nur für diesen Zweck existiert, ableiten zu lassen. In diesem Fall wäre unser T genau dann von einer array-Spezialisierung abgeleitet, wenn es von diesem Tag abgeleitet ist.struct array_tag {}; template<unsigned N, typename T> class array : public array_tag { public: static const unsigned size = N; typedef T value_type; //sth. cool here }; template<unsigned N, typename T> const unsigned array<N,T>::size; template<typename T, bool = boost::is_base_of<array_tag,T>::value> struct test { test() { cout << "Ich habe " << typeid(T).name() << " als Argument!" << endl; } }; template<typename T> struct test<T,true> { test() { cout << "Ich habe array<" << T::size << "," << typeid(typename T::value_type).name() << "> als Argument!" << endl; } };
-
OH MEIN GOTT!

Vielen herzlichen Dank!!! Das ist schlichtweg perfekt!!! Und Klassen die mehrmals von array erben kompilieren schlichtweg nicht!!!

U made my day

-
Coole Sache! Das kann ich auch gebrauchen!
Geht das auch mit mehreren Typen? Also ne Spezialisierung für andere Klassen und deren Ableitungen. So wie ich das sehe gibts nur 2 Möglichkeiten wegen dem bool