Template :"Nur best Typen"
-
Aber ein Template, dass nur für eine endliche Anzahl Typen funktionieren soll ist Quark.
Grund?
-
hustbaer schrieb:
Aber ein Template, dass nur für eine endliche Anzahl Typen funktionieren soll ist Quark.
Grund?
Es wiederspricht dem Sinn von templates.
-
Mal ganz davon abgesehen, dass es einfach nicht geht.

Spezialisierung bedeutet, dass die Implementierung für bestimmte Fälle anders aussieht (die spezialisierten Fälle nämlich
), als es das normale Template vorsieht.
Für alle nicht spezialisierten Fälle steht das Template trotzdem zur Verfügung, ob dies nun Sinn macht oder nicht.Wenn man nur eine begrenzte Menge an Typen hat, diese Menge aber so groß ist, dass es sich lohnt, dafür ein Template anzulegen, dann könnte man dafür das PIMPL Idiom benutzen.
D.h. man erstellt das Template in einer Implementierungseinheit, ohne dessen Interface öffentlich zu machen.
Öffentlich sind nur mehrere, spezialisierte Interfaces. Intern kann man dann verschiedene Ausprägungen des Templates benutzen, um die Funktionalitäten für die verschiedenen, spezialisierten Interfaces bereitszustellen.
-
@ Jihhaaaa:
Wenn ein Template nur zwei Typen (typedefs) unterstützen soll und diese Typen dann auch noch identisch sind, ist eine normale, nicht-generische Klasse eher angebracht.
-
Wohl kaum. Das kannst du so genauso gut unimplementiert lassen, dann gibt's einen (viel sinnvolleren) Compilerfehler.
Ok - da ist was dran ^^
Aber ein Template, dass nur für eine endliche Anzahl Typen funktionieren soll ist Quark.
Der OP wollte es für genau 2 Typen haben - entweder er schreibt 2 normale Klassen (was ich schwachsinnig fände) oder macht es so.
Mal abgesehen aus dem (mir unerschließlichem) Grund - ich würds mit Spezialisierung machen... Und ich finde auch nicht, dass es dem Konzept der Templates wiederspricht - das template ist für den Fall spezialisiert und für einen anderen Fall halt nicht definiert - hab noch nicht gelesen, dass das nicht gehen soll...bb
-
unskilled schrieb:
...das template ist für den Fall spezialisiert und für einen anderen Fall halt nicht definiert - hab noch nicht gelesen, dass das nicht gehen soll...bb
Wie willst Du das durch Spezialisierung hinbekommen? Insbesondere den Teil, dass ein Template für die nichtspezialisierten Fälle nicht definiert ist?
Spezialisierung ist nicht dafür da, die Benutzbarkeit eines Templates einzuschränken.
Sie soll die Funktionalität für ein Subset von Typen in bestimmter Weise implementieren. Wenn Du nur zwei spezialisierte Templates zur Verfügung stellt, aber das allgemeine weglässt, dann kannst Du in der Tat auch normale Klassen benutzen.
-
Tachyon ich denke dieses einfach Template könnte deine Frage beantworten.
template<bool> struct CTAssert; template<> struct CTAssert<true> {};Spezialisierung mit einer Forward-Deklaration kann aber dazu verwendet werden die Benutzbarkeit des Templates einzuschränken. Und in dem Beispiel oben ist es auch duraus sinnvoll. Auch wenn das Compilt-Time-Assert auch schöner imlementiert werden kann.
Quelle: http://safari.ibmpressbooks.com/0201704315/pref01 und soweit ich weiss steht es auch in "Modern C++ Design", welches ich aber nur teilweise gelesen habe.
Gruß
Baracke
-
Baracke_out schrieb:
[...]
Das ist ein ganz anderer Sinnzusammenhang.
Ich lasse mich allerdings gerne eines besseren belehren, wenn Du mir ein Beispiel für ein Template gibst (vielleicht ein Mini-Container), das mit genau zwei Typen (
doubleundstruct MyType{};) funktioniert, sonst aber mit keinem anderen Typen.
-
Naja... Nicht ganz so elegant, aber es geht...
template <class T> class test { private: test () {}; }; template < > class test <char> { public: test () {}; }; int main () { test <bool> eins; //fehler test <int> zwei; //fehler test <char> drei; //geht }Allerdings würde ich dann doch lieber meine Lösung von vorn mit der Exception bevorzugen ^^
Aber recht geben muss ich dir dann ja wo trotzdem, für den Fall, dass du das nicht zählst ^^
bb
edit:
mir ist noch ne lösung eingefallen - aber besser ist sie wahrscheinlich auch nicht xD
wenn man dann die funktion noch iwie in "invalid_template_argument" umbennent könnte man es so gar fast als benutzerfreundlich zählen
void get_linker_error (); template <class T> class test { public: test () { get_linker_error (); }; }; template < > class test <char> { public: test () {} }; int main () { test <bool> eins; test <int> zwei; test <char> drei; }PS: weiß nicht, ob #pragma da vll ne bessere möglichkeit bietet - aber das wär halt dann auch wieder msvc spezifisch...
-
unskilled schrieb:
Naja... Nicht ganz so elegant, aber es geht...
template <class T> class test { private: test () {}; }; template < > class test <char> { public: test () {}; }; int main () { test <bool> eins; //fehler test <int> zwei; //fehler test <char> drei; //geht }Allerdings würde ich dann doch lieber meine Lösung von vorn mit der Exception bevorzugen ^^
Aber recht geben muss ich dir dann ja wo trotzdem, für den Fall, dass du das nicht zählst ^^
bb
Wie gesagt, ich hätte gerne einen Container für die beiden genannten Typen. Er soll mit seiner Template-Implementierung genau die zwei Typen zulassen. Alle anderen aber nicht. Die hier gezeigten Beispiele sind Spezialimplementierungen für die Spezialisierung.
Dein Beispiel hat z.B. die allgemeine Implementierung mit dem Private-Ctor und eine spezialialisierte Version für
charmit eigener Implementierung. Für weitere, zulässige Typen müsstest Du weitere Implementierungen bereitstellen.
Du musst also für N Typen auch N Implementierungen spezialisieren, sowie denn allgemeinen Fall verbieten. Der Fall tes TOs ist sogar noch schlimmer, da die beiden Typen die gleiche Implementierung benutzen sollen. Man muss also zwei Spezialisierungen schreiben, die die gleichen Algorithmen beinhalten. Dann kann man auch gleich zwei Klassen schreiben, und sich das verbieten von nicht erwünschten Typen sparen.Mal ganz davon abgesehen sind, so wie ich das jetzt sehe, die beiden Typen mit denen der TO sein Template ausprägen will in Wirklichkeit nur ein Typ.
-
Hab noch ma Beitrag editiert ^^
Und ja - das hatte ich ja vorhin schon bemerkt, dass es doch nur einer ist ^^Von daher ist das template vll wirklich ein wenig... wie soll ich sagen... fehl am platz ^^
also hast ja recht

bb
-
Nexus schrieb:
@ Jihhaaaa:
Wenn ein Template nur zwei Typen (typedefs) unterstützen soll und diese Typen dann auch noch identisch sind, ist eine normale, nicht-generische Klasse eher angebracht.Werde ich immer so überlesen? :p
-
weils sonst unfair mir gegenüber gewesen wäre ^^
(ich war eher)unskilled schrieb:
PS: warum verschiedene typedefs für gleiche typen? Oo
:p :p :p
-
Aber ich war es, der als erster darauf hingewiesen hat, normale Klassen zu nehmen. :p
Nein, jetzt mal im Ernst, warum sollte man in diesem Fall (1 zugelassener Typ) ein Template nehmen? Wie bist du auf die Idee gekommen, Jihhaaaa?

-
Ich habe meinen vorletzten Beitrag nochmal erweitert (also den Beitrag vor diesem).

-
Du musst also für N Typen auch N Implementierungen spezialisieren, sowie denn allgemeinen Fall verbieten.
das müsste man bei richtigen Klassen auch - also N klassen für N typen (wobei ich nen kleines n nehmen würde xP )
den allg Fall verbieten.. das is ja rel. schnell gemacht...
also ich denke, es würde beim programmieren mit der klasse einfach besser aussehen - und für den compiler ist es wahrscheinlich egal, ob template oder eigene klasse...und wer will schon so ne klassen:
class Taufgabe_int {}; class Taufgabe_bool {}; class Taufgabe_vector_const_iter_shouldnt_be_the_end_iterator_of_an_vector_or_deque_or_list_or_something_like_this {/*toll, oder : >*/};^^
bb
-
unskilled schrieb:
das müsste man bei richtigen Klassen auch - also N klassen für N typen (wobei ich nen kleines n nehmen würde xP )
Darum geht es doch. Wenn man eh nur N Fälle zulassen will, und die Menge N überschaubar bleibt, nimmt man besser Klassen anstatt Klassen-Templates. Man kann zweiteres natürlich schon nehmen, aber das ist irgendwie Schwachsinn.
-
ich würd die template-lösung (für mehr als einen typen ^^) der klassen-name-mit-variablen-typ-verunstalten-version vorziehen - selbst, wenn es mehr arbeit ist...
-
Tachyon schrieb:
Darum geht es doch. Wenn man eh nur N Fälle zulassen will, und die Menge N überschaubar bleibt, nimmt man besser Klassen anstatt Klassen-Templates. Man kann zweiteres natürlich schon nehmen, aber das ist irgendwie Schwachsinn.
Wenn sich die Klassen aber nur im Typ unterscheiden, kann man sich eine grosse Menge Code sparen, und als Nebeneffekt erhält man noch eine bessere Übersicht und Wartbarkeit. Ausserdem muss man nicht für jede Klasse den Bezeichner kennen.
Im Notfall kann man ja immer noch
typedefsmachen (was ich aber sehr unschön finde)...
-
Nexus schrieb:
Tachyon schrieb:
Darum geht es doch. Wenn man eh nur N Fälle zulassen will, und die Menge N überschaubar bleibt, nimmt man besser Klassen anstatt Klassen-Templates. Man kann zweiteres natürlich schon nehmen, aber das ist irgendwie Schwachsinn.
Wenn sich die Klassen aber nur im Typ unterscheiden, kann man sich eine grosse Menge Code sparen, und als Nebeneffekt erhält man noch eine bessere Übersicht und Wartbarkeit. Ausserdem muss man nicht für jede Klasse den Bezeichner kennen.
Im Notfall kann man ja immer noch
typedefsmachen (was ich aber sehr unschön finde)...Nein, kann man eben nicht. Man kann nicht spezialisieren, ohne dass man für jede Spezialisierung eine Implementierung liefert.
Entweder, man macht ein allgemeines Template, und lebt damit, dass jeder Typ erlaubt ist, oder man implementiert N mal spezialisiert. So oder so.
Die beste Möglichkeit ist, denke ich, die von mir oben genannte PIMPL-Idiom-Variante.