Klassen template methode Rückgabewert abhängig von Templatetyp
-
Ich brauche zwei Klassen die sich nur in zwei wesentlichen Dingen unterscheiden: der Typ eines Members und der enum-wert den eine Methode zurückgibt. Ich würde das gerne als Template realisieren um massive Codeduplikation zu vermeiden. Den Member Typ als Template-Parameter festzulegen ist kein Problem, aber wie realisiere ich es, dass die Funktion abhängig vom Membertyp den richtigen enum-Wert zurückliefert, wobei diese Auswertung am besten noch zur Kompilezeit geschehen soll. Hat jemand eine Idee?
-
also existiert eine injektion von den template-typen in die enum-werte?
dann kannst du doch sowas machen (ungetestet und aus dem stehgreif):
enum Types // Oder Safe-Enums mit C++11 bzw. Safe-Enum-Idiom in C++03 { tBool, tInt }; template<typename T> struct Injection; template<> struct Injection<bool> { static const Types Value = tBool; }; template<> struct Injection<int> { static const Types Value = tInt; }; // Oder allgemein gegen diesen Boilerplate-Code: #define MyLib_MakeInjection(TypeName, EnumName) \ template<> \ struct Injection<TypeName> \ { \ static const Types Value = EnumName \ }; template<typename T, template<class> class MyInjection = Injection> struct MyClass { T MyData; Types Type() const { return MyInjection<T>::Value; } };
edit: falscher kasus.
-
Danke, ich denke so sollte es funktionieren.
-
Ich würde das gerne als Template realisieren
Du kannst auch private von einer gemeinsamen Basisklasse erben, du kannst die Memberfunktion spezialisieren, du kannst .... auch wild mit defines arbeiten.
-
Funktioniert super mit der injection. Nun habe ich in eine Methode noch die Anforderung, abhängig vom typename T eine Zeichenkette auszugeben. Da habe ich noch keine Idee wie das laufen soll. Meine Versuche eine const char[] in die Injection zu packen, haben leider nicht funktioniert.
-
entweder mit meinem alten ansatz:
template<typename T> struct Injection; template<> struct Injection<bool> { static char const* const Value; }; template<> char const* const Injection<bool>::Value = "bool"; template<> struct Injection<int> { static char const* const Value; }; template<> char const* const Injection<int>::Value = "int"; // Komfort: #define MyLib_MakeInjection(TypeName) \ template<> \ struct Injection<TypeName> \ { \ static char const* const Value; \ }; \ template<> \ char const* const Injection<TypeName>::Value = #TypeName; template<typename T, template<class> class MyInjection = Injection> struct MyClass { T MyData; char const* Name() const { return MyInjection<T>::Value; } };
oder vererbung:
template<typename T> struct TypeNameCStr; template<> struct TypeNameCStr<bool> { char const* Name() const { return "bool"; } }; template<> struct TypeNameCStr<int> { char const* Name() const { return "int"; } }; // Komfort: #define MyLib_MakeInjection(TypeName) \ template<> \ struct TypeNameCStr<TypeName> \ { \ char const* Name() const \ { \ return #TypeName; \ } \ }; MyLib_MakeInjection(float) MyLib_MakeInjection(char) template<typename T> struct MyClass : public TypeNameCStr<T> { // ... };
ich weiss gar nicht was ihr gegen makros habt, die das ganze wesentlich leserlicher machen.
-
template<> struct Injection<int> { static char const* const Value; }; template<> char const* const Injection<int>::Value = "int";
Gibt ein "template header not allowed in member definition of explicitly specialized class"
Wenn ich es ändere in
template<> struct Injection<int> { static char const* const Value; }; char const* const Injection<int>::Value = "int";
Kompiliert es zwar, aber ich bekome ein "multiple definition of Injection<int>::Value"
-
Das
char const* const Injection<int>::Value = "int";
darf nicht im Header stehen, sonst wird es in jeder Übersetzungseinheit, in der der Header eingebunden wird neu definiert