Template-Tricks
-
Also soweit meinte ich das zumindest schon verstanden zu haben, ich meinte vor allem, was ist der Unterschied zu folgendem:
template<class T> struct is_policy_cons { static const bool value = false; }; template< typename H, typename T > struct is_policy_cons< policy_cons<H,T> > { static const bool value = true; }; template< > struct is_policy_cons< null_type > { static const bool value = true; };Edit: Das wäre jetzt die Variante, die ich erstmal intuitiv zur Lösung des Problems gewählt hätte, aber die muss ja offenbar der Variante da oben unterlegen sein.
Edit #2: Oh, die Variante da oben catched auch alle abgelittenen Klassen und mein Template so erstmal nicht, oder?Okay: Diesen Trick klassifiziere ich unter "Matche den speziellen Template-Typ und alle abgelittenen Typen. Fällt mir auch erstmal keine
eleganteandere Lösung ein. (Wobei man aber sagen muss, dass diese Lösung hässlich ist und eine schwäche des Template-Systems darstellt, hehe)
-
Gibt es denn eigentlich irgendeinen Grund, aus dem man folgendes Konstrukt nicht erlaubt hat?
template< typename D, template<typename,typename> class B, typename B1, typename B2 > // B ist also ein unspezialisiertes Template mit 2 Parametern struct is_template_base_of< D, B<B1,B2> > { }; template< typename T > struct is_policy_cons3 : public is_template_base_of< T, policy_cons > { };
-
Decimad schrieb:
Gibt es denn eigentlich irgendeinen Grund, aus dem man folgendes Konstrukt nicht erlaubt hat?
Jo, is sogar ziemlich simpel: Es macht keinen Sinn. Oder nach welchem Verfahren soll der Compiler B1 und B2 erraten?
-
Nunja, das Erraten soll dann stattfinden, wenn D auf ein Vorkommen von B als Basis untersucht wird
oder so ähnlich. B1 und B2 sind natürlich unnötig, da hast du Recht. Ich frickel mal weiter rum. Dieser Funktionstrick ist irgendwie so hässlich, da muss es doch was von Ratiopharm geben.
-
Auf die Sekunde genau editiert

-
Decimad schrieb:
[...] ich meinte vor allem, was ist der Unterschied zu folgendem:
[...]Es tut etwas völlig anderes?
Decimad schrieb:
Edit #2: Oh, die Variante da oben catched auch alle abgelittenen Klassen und mein Template so erstmal nicht, oder?
Genau das ist der Sinn, ja...
Decimad schrieb:
Dieser Funktionstrick ist irgendwie so hässlich, da muss es doch was von Ratiopharm geben.
Was findest du daran denn so hässlich, ich find den eigentlich vergleichsweise elegant!?
Kannst ja auch mal einen Blick auf std::is_base_of werfen...
-
Na aber is_base_of kann auch nicht mit unspezialisierten Template-Klassen umgehen.
Und hässlich daran ist folgendes: Das Templete-System ist "zu schwach" und dann fängt man an, hinter der Template-Fassade freie Template-Funktionen zu deklarieren um auf das Überladungs-System auszuweichen zum Zwecke der statischen Typanalyse.
Da steht natürlich noch die Frage im Raum, wozu dieser spezielle Check dienen soll, und ob man mit ihm nicht versucht, die leider noch fehlenden Concepts zu simulieren...
-
Decimad schrieb:
Na aber is_base_of kann auch nicht mit unspezialisierten Template-Klassen umgehen.
Du meinst Klassentemplates? Wie genau sollte das auch funktionieren, ein Template ist keine Klasse (sondern eben ein Template), da von einer Basisklasse zu sprechen, macht also gar keinen Sinn!?
-
Na das funktioniert genau so, wie das Quelltextbeispiel im ersten Posting darstellt.
Davon zu sprechen, dass die Spezialisierung eines Klassentemplates Basis einer anderen Klasse ist, ergibt in meiner Logik irgendwie Sinn.
-
Luabind... ich habe mal versucht, den Quellcode zu verstehen, weil ich ein paar Anpassungen machen wollte... nach einer Quellcode-Datei hab ichs sein lassen.
Dafür ist es aber auch eine der coolsten Bibliotheken (aus Anwendersicht), mit denen ich je gearbeitet hab.
-
Decimad schrieb:
Davon zu sprechen, dass die Spezialisierung eines Klassentemplates Basis einer anderen Klasse ist, ergibt in meiner Logik irgendwie Sinn.
Meinst du mit "Spezialisierung eines Klassentemplate" eine Instanz desselben?
-
Ja.
-
In dem Fall versteh ich nicht, was genau das Problem mit std::is_base_of sein soll!?
-
template< typename H, typename T > struct policy_cons { typedef H head; typedef T tail; }; struct mycons : public policy_cons< int, int > { }; int main(int argc, char* argv[]) { std::cout << std::is_base_of< policy_cons, mycons >::value; // Schade... return 0; }Edit: Mit Ja. meinte ich eine beliebige Instanz desselben, nicht eine bestimmte.
Dort liegt das Problem. Das Konstrukt, dass ich in meinem OP aus den luabind-Quellen kopiert habe, löst genau das Problem.
Edit: Und es löst das Problem auf eine Art und Weise, die nicht generalisierbar ist. Für jedes Klassentemplate muss man einen neuen Satz von Funktionen definieren.
-
Was genau ist der Sinn, wofür denkst du das zu brauchen!? Imo mach das keinen Sinn, da Ableitungsbeziehungen Beziehungen zwischen Klassen sind und nicht zwischen Templates. In deinem konkreten Beispiel ist genau eine Instanz von policy_cons Basis von mycons und nicht jede beliebige Instanz. Ich vermute, dass du da gerade entweder versuchst, ein Problem zu lösen, das keines ist, versuchst eine Lösung zu finden, zu der es kein Problem gibt oder einen Weg verfolgst, der zu nichts führt...
-
Ich versuche damit gar nichts zu lösen. Die Quellen sind so aus luabind kopiert und ich denke die Jungs hinter luabind machten so Template-Parameter-type-checks aufgrund nicht vorhandener C++-Concepts.
Und dieser Hack oder dass es dann die C++-Concepts machen müssen ist für mich ein Beleg dafür, dass Klassentemplates keine Form von Metatyp im C++-Typsystem sind, das System in sich sozusagen inkonsistent ist.
-
Ok, jetzt kann ich leider nicht mehr folgen. Ich bezweifle, dass ein Release von luabind Code enthält, der nicht kompilieren wird, weil er keinen Sinn macht. Ergo kann es nicht sein, dass obiger Code "aus luabind kopiert" ist. Ich versteh nicht, worauf du hinaus willst und wieso das C++ Typsystem inkonsistent sein soll, weil es die willkürliche Vermischung von Konzepten völlig verschiedener Ebenen nicht erlaubt, erschließt sich mir auch nicht...
Also: Was genau ist deine Frage?
-
Natürlich steht das is_base_of, so wie ich es oben gepostet habe, nicht in deren Quelltext. Aber eben das funktionierende Äquivalent dazu (siehe OP).
Und es ist natürlich nicht das komplette Äquivalent, weil die Implementierung eben nur für dieses eine spezielle Klassentemplate funktioniert und für jedes andere Klassentemplate erneut implementiert werden muss.
-
Ja!?
-
Na, ist ja auch egal. Was das Konstrukt aus dem OP nun lösen soll, ist mir ja inzwischen klar und ob es gut ist, dass es keine generelle Lösung dafür gibt, sowie ob die Lösung selber elegant aussieht, das mag wohl im Auge des Betrachters liegen.