Verschiedene Policies ueber Template Spezialisierung geht nicht
-
Hallo,
Ich wollte gerne ausprobieren (G++ 4.3.2 auf Debian) ob ich per Template Spezialisierung zwischen der Verwendung verschiedener Policies unterscheiden kann, leider kompiliert mein Code nicht, warum?!
template< typename T > class NewPolicy; template< typename T > class MallocPolicy; template< typename U > class UserClass; /* UserClass implementations //*/ template< typename U > class UserClass : public NewPolicy< U > { public: void doSomething() { // ... } // ... }; template<> class UserClass< char > : public MallocPolicy< char > { void doSomething() { // ... } // ... }; /* policies, eine benutzt 'new', die andere 'malloc' daher der Name, aber soll nur ein Bsp sein.. //*/ template< typename T > class NewPolicy { // ... }; template< typename T > class MallocPolicy { // ... }; /* main //*/ int main() { UserClass< int > uc_1; uc_1.doSomething(); // verwende automatischerweise 'new' wegen NewPolicy fuer alles was hier mit 'int' zu tun hat UserClass< char > uc_2; uc_2.doSomething(); // verwende automatisch die MallocPolicy fuer alles was mit 'char' zu tun hat return 0; }Gut, die Template Spezialisierung ohne Vererbung kompiliert. Das ganze mit Vererbung Unterschiedlicher Policy Klassen, ohne dass diese selber wiederum Template Parameter besitzen, kompiliert ebenfalls. Ich kann, ausserdem, im Fall der NewPolicy diese sogar als Template Klasse kompilieren und den Template Typ U uebergeben. Aaaaaaber, das ganze scheitert, sobald ich versuche nicht einen Template Typ sondern einen "konkreten" Typ, zB int, char, std::string, etc - uebergebe.
Die Error Meldungen:
error: invalid use of incomplete type 'struct MallocPolicy< char >'
error: declaration of 'struct MallocPolicy< char >'Fragen:
1. Woran liegts? Wie bekomme ich meinen Code kompiliert?2. Ausserdem, ist es bei Template Spezialisierungen eigentlich nicht irgendwie moeglich zB so eine Funktion wie "doSomething()" fuer beide Implementierungen zugaenglich zu machen? Klar, afaik werden nur die Versionen kompiliert, die auch benoetigt werden, aber dennoch ist es in gewisser Weise redundanter Code. Kann man dem nicht irgendwie auskommen?

-
Fabeltier schrieb:
1. Woran liegts? Wie bekomme ich meinen Code kompiliert?
Die Klassentemplates
NewPolicyundMallocPolicysollten vor dem KlassentemplateUserClassdefiniert werden und nicht nur deklariert. Sonst geht das nicht.Fabeltier schrieb:
2. Ausserdem, ist es bei Template Spezialisierungen eigentlich nicht irgendwie moeglich zB so eine Funktion wie "doSomething()" fuer beide Implementierungen zugaenglich zu machen? Klar, afaik werden nur die Versionen kompiliert, die auch benoetigt werden, aber dennoch ist es in gewisser Weise redundanter Code. Kann man dem nicht irgendwie auskommen?
Eine Möglichkeit wäre eine Art von Pimpl-Idiom. Du schreibst einfach noch eine dritte Klasse, vielleicht in einem
namespace detail, und definierst dort die Methode. Bei den anderen erstellst du diese Klasse als Member und leitest alle Aufrufe jeweils darauf um. Dadurch musst du nicht die ganze Methode immer neu implementieren, sondern kannst nur immer eine Umleitung hinschreiben
Etwas anderes ist mir nicht bekannt.Grüssli
-
Danke, es kompiliert!!!
Nur, frag ich mich jetzt etwas warum reicht eine Forward Deklaration nicht? Hum, hat vllt auch mit der "Compile-time Aktivitaet" von Templates zu tun, also das nur der Code compiliert wird der hier instantiiert wird bei Templates?
Zu 2. so eine "Umgehung" ueber eine dritte Klasse hatte ich mir auch schon ueberlegt, das scheint aber auch nur die intuitive Vorgehensweise zu sein. mit Namespace scheint das einigermassen brauchbar zu sein, super! :xmas1: :xmas2:
-
Fabeltier schrieb:
Nur, frag ich mich jetzt etwas warum reicht eine Forward Deklaration nicht? Hum, hat vllt auch mit der "Compile-time Aktivitaet" von Templates zu tun, also das nur der Code compiliert wird der hier instantiiert wird bei Templates?
Weil das allgemein so ist, eine Klasse muss definiert sein, wenn man von ihr ableiten will. Du kannst bei normalen Klassen auch nicht von einer Deklaration ableiten, da wird dir jeder Kompiler rumschreien, bis deine Ohren abfallen

Wieso dem so ist, da musst du das Standardkomittee fragen. Aber ich nehme mal an, man hat es gemacht, um die Arbeit des Interpreters zu vereinfachen.
Grüssli