wofür templates?
-
-
@spacelord
in einen java-Vector tut man normalerweise nur Objete eines bestimmtes Typs rein und weiß dann ja auch wie man casten muß..Vector autos= new Vector(); Auto bmw= new Auto("BMW"); autos.addElement(bmw); Auto car= (Auto) autos.get(0); //casten und fertig, wenn der Cast bei Laufzeit //schief läuft, weiß man das was nich stimmt
[ Dieser Beitrag wurde am 04.06.2003 um 10:27 Uhr von crass editiert. ]
-
Spacelord: siehe crass' Antwort
Ausserdem, hattest du nicht für Templates stattdessen argumentiert? Templates sind komplett statisch, wo ist *da* deine Dynamik?
-
Was ist normal??
Wenn hier eine Objectoberklasse als Vorteil angepriesen wird,sollte es doch erlaubt sein aufzuzeigen das ein inhomogener Vektor(der durch Object ja möglich ist) auch Probleme mit sich bringt.Ich kann doch nicht auf der einen Seite sagen,"Guck mal hier in dem Objejt-Vector kann ich alle erdenklichen Objekte speichern" und dann sag ich das man aber nur eine Sorte darin speichern sollte weil es Mist ist damit zu arbeiten.
-
niemand hat gesagt (so weit ich weiß) daß es ein Vorteil ist alle möglichen Objekt-Typen speichen zu können, es ging hauptsächlich darum, ob Templates notwendig sind und ob man es nicht gleichwertig durch diese Technik ersetzen kann..(wobei ich gar nicht der Meinung bin, daß es völlig gleichwertig ist)
[ Dieser Beitrag wurde am 04.06.2003 um 10:36 Uhr von crass editiert. ]
-
Makro deshalb, weil *im wesentlichen* nichts anderes passiert, als dass die Parameter eingesetzt werden (von Sachen wie Spezialisierung und speziellen Lookup-Regeln abgesehen). Spezialfall deshalb, weil die Möglichkeiten der Code-Transformation doch sehr begrenzt sind.
Hm, obwohl ich mich bemühe, kann ich mich hier nicht deiner Ansicht anschließen.
An den C++ Templates sind automatische Typherleitung (Funktionstemplates), Spezialisierung, 2-Phasenlookup, export und co ja gerade das entscheidene.Wenn du das jetzt alles weglässt, dann sehe ich eindeutig den Makrocharacter. Dann sehe ich allerdings nicht mehr viel von C++ Templates.
Das ist mir einfach ein wenig zu sehr abstrahiert und vereinfacht.[...]es ging hauptsächlich darum, ob Templates notwendig sind und ob man es nicht gleichwertig durch diese Technik ersetzen kann..(
Beides lässt sich meiner Meinung nach leicht beantworten:
1. Nein, Templates sind strenggenommen nicht notwendig (genau wie Klassen und Vererbung)
2. Nein, gleichwertig lassen sie sich durch dynamische Polymorphie nicht ersetzen. Allein schon weil in Sprachen wie C++ Compilezeitfehler noch was anderes als Laufzeitfehler sind und man immer erstere bevorzugt.
-
@HumeSikkins: Du bist abschätzig gegenüber Makros, nur weil du nur C Makros kennst (kann ich dir nich verübeln :D). Bashar hat ja schon von irgendwelchen Common-Lisp Makros geredet - ich kenn nur Scheme Makros. Und diese Scheme-Makros sind gar nicht mal übel.
-
Nur so kann man zB bei jedem Objekt garantieren, daß es Methoden hat, die jedes Objekt haben sollte(bei einer praktischen Sprache die auf die Bedürfnisse der Programmierer zugeschnitten ist zumindest), zB toString().
Kann mit bitte einer erklären, warum mein Vogel und mein Auto jetzt ein toString() haben sollte und wie ich diese Methode vernüpftig implementieren sollte (inhaltlich).
jo, OO halt ich für "natürlich"...damit mein ich eine Technik, die dem menschlichen Denken nahe liegt.. Menschen stellen sich würd ich mal sagen, normalerweise alles irgendwie als Objekt (Sache) vor, auch Verallgemeinerungen und Konkretisierungen (wie bei Vererbungen) von Dingen und Personen sind typisch fürs normale Denken
Ja und es ist ja völlig abwegig sich vorzustellen, dass es eine Kiste für Eier und eine Kiste für Äpfel gibt. Nein, eine normal denkender Mensch denkt nur an Kisten, in denen Objekte sind und geht davon aus, dass nur Objekte einer Art drin sind. Sollte versehentlich doch mal eine andersgeartetes Objekt in die Kiste gelangen, ist das eben ein Fehler. Kannst du so denken? Ich jedenfalls nicht.
-
Original erstellt von HumeSikkins:
**
An den C++ Templates sind automatische Typherleitung (Funktionstemplates), Spezialisierung, 2-Phasenlookup, export und co ja gerade das entscheidene.
**Wieso ist das entscheidend? Mag ja sein, dass man damit tolle Sachen machen kann, aber das ist alles nur eine Folge aus der Grundidee, Komponenten zur Übersetzungszeit zu parametrieren.
Was ist eigentlich Two-Phase-Lookup, und warum ist es so toll, dass du es mit aufzählst?
-
Original erstellt von Helium:
Ja und es ist ja völlig abwegig sich vorzustellen, dass es eine Kiste für Eier und eine Kiste für Äpfel gibt. Nein, eine normal denkender Mensch denkt nur an Kisten, in denen Objekte sind und geht davon aus, dass nur Objekte einer Art drin sind. Sollte versehentlich doch mal eine andersgeartetes Objekt in die Kiste gelangen, ist das eben ein Fehler. Kannst du so denken? Ich jedenfalls nicht.Ich weiß nicht, ob du einfach ein beschissenes Beispiel ausgesucht hast, was du dann nach Schema F verteidigst ... aber ich hab überhaupt kein Problem, mir eine Kiste vorzustellen, in die ich alles packen kann :p In der realen Welt gibt es keine statischen Typen.
-
*Name Lookup
Templates introduce a new wrinkle to name lookup. (See Chapter 2 for the non-template rules of name lookup.) When compiling a template, the compiler distinguishes between names that depend on the template parameters (called dependent names) and those that do not (non-dependent names). Non-dependent names are looked up normally, where the template is declared. Dependent names, on the other hand, must wait until the template is instantiated, when the template arguments are bound to the parameters. Only then can the compiler know what those names truly mean. This is sometimes known as two-phase lookup.
*
-
für Debug oder log-Zwecke ist die toString()-methode nützlich, egal für welches Objekt. Auch für nen Vogel.. wenn du sie nicht brauchst-bitte. Zwingt dich ja niemand.
Ja und es ist ja völlig abwegig sich vorzustellen, dass es eine Kiste für Eier und eine Kiste für Äpfel gibt. Nein, eine normal denkender Mensch denkt nur an Kisten, in denen Objekte sind und geht davon aus, dass nur Objekte einer Art drin sind. Sollte versehentlich doch mal eine andersgeartetes Objekt in die Kiste gelangen, ist das eben ein Fehler. Kannst du so denken? Ich jedenfalls nicht.
ich find die zweite Sichtweise nicht völlig abwegig. Und wenn man Templates benutzt , hat man ja auch nicht wirklich konkret ne Kiste für Äpfel gecodet , sondern ertsmal ne Schablonen-Kiste, in die man dann was reinsetzt.. bei COntainern is das aber wie ich schon sagte, schon ok. Nur außerhalb von Container-Klassen hab ich bisjezt noch nie Templates verwendet oder vermißt
-
Original erstellt von crass:
Nur außerhalb von Container-Klassen hab ich bisjezt noch nie Templates verwendet oder vermißtdann kann ich gleich assembler programmieren - nur weil du ein feature nicht zu schaetzen weisst, heisst es noch lange nicht das man es nicht braucht oder das es nutzlos ist.
Ich bin Humes Meinung. Allerdings muss ich sagen dass die templates die C++ momentan kann nur ein kleiner Anfang sind -> wenn man Modern C++ Design liest oder sich boost ansieht, dann sieht man welche Kapazitaeten das ganze hat.
Mag sein das Lisp das schon lange kann. Und mag sein das Lisp es nicht templates sondern Makro nennt. Ich kann kein Lisp, aber kann mir mal jemand sagen inwiefern Lisp Makros die selben maengel haben wie C Makros und inwiefern Lisp Makros die selben Vorteile von C++ templates haben?
Man darf von C++ templates nicht immer nur im Stile von Container<T> denken. C++ templates bieten eine (leider noch zu beschraenkte Moeglichkeit) code zu schreiben der waehrend der compile Time ausgefuehrt wird.
Wenn Lisp das schon lange kann dann ist das schoen, aber fuer mainstream Sprachen ist das ein neues feature dass man code schon zur Compiletime ausfuehren kann.
Und wie Hume schon sagte, nichteinmal ein Container<T> template kann man 1:1 mit Polymorphie uebersetzen. Denn dann fehlt die statische Typenpruefung.
-
Original erstellt von Shade Of Mine:
**
Mag sein das Lisp das schon lange kann. Und mag sein das Lisp es nicht templates sondern Makro nennt. Ich kann kein Lisp, aber kann mir mal jemand sagen inwiefern Lisp Makros die selben maengel haben wie C Makros und inwiefern Lisp Makros die selben Vorteile von C++ templates haben?
**Wie gesagt, Lisp-Makros funktionieren ganz anders als cpp Makros.
In Lisp gibt es nur eine syntaktische Struktur, die Liste. Jeglicher Code wird vom Reader (Parser) intern als einfach verkettete Liste abgelegt. Grundsätzlich gilt, dass das erste Element der Liste bestimmt, welche Bedeutung die ganze Konstruktion (genannt Form) hat. Entweder es ist eine Funktion, oder es ist ein Makro, oder es ist eine sogenannte "special form".
Funktionen funktionieren wie aus anderen Programmiersprachen bekannt: Die Parameter werden ausgewertet (von links nach rechts) und der Funktion übergeben. Das ganze zur Laufzeit.
Makros dagegen bekommen ihre Parameter unausgewertet. Man kann sich Makros wie Funktionen vorstellen, die zur Compilezeit abgearbeitet werden. Das was sie zurückgeben (eine Liste) wird vom Compiler weiterverarbeitet. Special Forms sind eingebaute Operatoren wie IF oder QUOTE, die haben jeweils spezifische Auswertungsregeln.Mal ein Beispiel aus "On Lisp". Angenommen, Common Lisp hätte keine WHILE-Schleife. Dann müßte man immer sowas schreiben:
(do () ((not <bedingung> )) ... code ...)
also schreibt man flux ein Makro, das diese Konstruktion zur Verfügung stellt:
(defmacro while (cond &body body) `(do () ((not ,cond)) ,@body))
Es sind theoretisch beliebige Verarbeitungen möglich, nicht nur Einsetzen der Parameter in Schablonen, wie oben. Compilezeit-Fakultät scheint ja ein sehr beliebtes Beispiel zu sein, also los:
(defmacro ct-fact (n) (labels ((fact (n) (if (zerop n) 1 (* n (fact (1- n)))))) (if (constantp n) (fact n) (error "n must be a constant."))))
(ct-fact 30) würde jetzt beim Übersetzen durch 265252859812191058636308480000000 ersetzt werden.
Lisp-Makros haben ihre eigenen Tücken, z.B. dass Symbolnamen aus der Umgebung eingefangen werden können, oder dass man darauf achten muß, dass ein Argument nicht mehr als einmal ausgewertet wird, und dass die übergebenen Argumente möglichst von links nach rechts (wenn überhaupt) ausgewertet werden ...
Ich hoffe du kannst dir jetzt selbst ein Bild machen, inwiefern das die Nachteile oder Vorteile von cpp Makros oder Templates hat.PS: Lisp war schonmal Mainstream-Sprache (70er/80er) und wird es vielleicht wieder werden.
[ Dieser Beitrag wurde am 04.06.2003 um 18:16 Uhr von Bashar editiert. ]
-
Wieso ist das entscheidend? Mag ja sein, dass man damit tolle Sachen machen kann, aber das ist alles nur eine Folge aus der Grundidee, Komponenten zur Übersetzungszeit zu parametrieren.
Ich kann dir ehrlich gesagt nicht folgen. Mir geht es bei Templates (wie bei vielen anderen Dingen auch) genau um tolle Sachen.
Was die Grundidee ist kann ich nicht beurteilen. Da ist mein Wissen derzeit noch viel zu beschränkt für.Was ist eigentlich Two-Phase-Lookup, und warum ist es so toll, dass du es mit aufzählst?
Ich habe nicht gesagt das es toll ist. Ich habe ein paar Dinge aufgezählt die für mich über das Makro-Konzept (so wie ich es verstehe) hinaus gehen. Und das die Übersetzung von Templates in zwei Phasen abläuft ist für mich so ein Ding.
Ansonsten:
Das Thema Lisp finde ich persönlich zwar höchst interessant, ich verstehe allerdings nicht was genau das mit der Frage zu tun hat. So wie ich das verstanden habe ging es doch eher darum wozu man Templates in *C++* (oder zur Not noch in Sprachen die ähnlich statisch wie C++ sind) braucht. Nicht ob und wie man sie in Smalltalk, Lisp oder Dynamic-Elefant einsetzen kann.Das ich nicht auf die Idee komme in einem Lisp-Forum die Einführung von C++ Templates zu fordern sollte doch eigentlich klar sein.
Zwischen Lisp, Smalltalk und C++ scheint es mir wichtigere Unterschiede als Templates zu geben.
(defmacro ct-fact (n)
(labels ((fact (n) (if (zerop n)
1
(* n (fact (1- n))))))
(if (constantp n)
(fact n)
(error "n must be a constant."))))Und da regen sich alle über die hässliche Syntax von C++ auf
Man muss sich scheinbar auch in anderen Sprachen erstmal an die Syntax gewöhnen bevor man sie mögen kann
-
Wir sind immer noch bei der Frage, ob Templates eine Form von Makro sind oder nicht. Vielleicht sind sie es nicht. Vielleicht kann man sagen, dass Templates versuchen, das deklarativ zu lösen, was Makros prozedural tun.
Im übrigen war der Lisp-Code hübsch, bis du die Code-Tags und damit die Einrückung entfernt hast :p
-
Original erstellt von Shade Of Mine:
Man darf von C++ templates nicht immer nur im Stile von Container<T> denken. C++ templates bieten eine (leider noch zu beschraenkte Moeglichkeit) code zu schreiben der waehrend der compile Time ausgefuehrt wird.Fantastisch. Geht aber auch in C.
#error "Hallo Welt"
Man kann sogar Berechnungen durchführen, schlimmstenfalls muss man rekursiv Dateien einbinden (Makrowerte erraten [#iffen], #undefen, #neudefen und #inkludieren), was ab einem bestimmten Limit genau so implementierungsspezifisch wie C++-Templates wird. Dabei erzeugt man idR eine Folge von Token, zB '2*4*6*8', die nur ein blinder Optimierer stehenlässt.
fuer mainstream Sprachen ist das ein neues feature dass man code schon zur Compiletime ausfuehren kann.
Jaja.
-
@Daniel E.
Was ist es was du mit deinem Beitrag sagen willst? Ist der von dir vorgeschlagene Ansatz zu Templates äquivalent (aus praktischer Sicht)? Oder ist das mehr in Richtung: "Prinzipiell machbar, aber völlig sinnlos da viel zu aufwendig, fehleranfällig und hässlich. Wollte damit aber zeigen, dass Templates nichts neues sind"
gemeint?Wenn ich mir so vorstelle wie jemand die Spirit-Lib (habe gerade die Doku offen, deshalb gerade dieses Beispiel. Jedes andere tut's auch) mit Hilfe des Präprozessors in C realisiert, stelle ich fest, dass ich deinen Punkt nicht sehe.
-
Original erstellt von HumeSikkins:
Oder ist das mehr in Richtung: "Prinzipiell machbar, aber völlig sinnlos da viel zu aufwendig, fehleranfällig und hässlich. Wollte damit aber zeigen, dass Templates nichts neues sind"
gemeint?Was Compilezeitprogramme betrifft, meinte ich genau das. Andere Funktionalität ist mit templatefreiem ISO-C++ nicht wirklich nachzubilden.
-
Wieso reden hier alle von brauchen?
Als ich mit C++ angefangen hab konnte ich nicht viel mehr als schleifen, if, cin und cout... und ich konnte ziemlich alles was mit in den Sinn kam programmieren.
Dann hab ich irgendwo die OOP Geschichte gelernt.... ich konnte zwar nichts neues programmieren, aber dafür schneller, wiederverwendbarer und effektiver.
Ähnlich verhielt sich das mit vielen Dingen, ob überladene Operatoren, Pointer, STL, Arrays oder eben Templates...
Wenn man sie verwendet kann man ne Menge Zeit sparen und der Quellcode wird wesentlich schöner, wiederverwendbarer und kürzer.
Aber BRAUCHEN tut man all diese Dinge nicht...
Templates sind eine feine Sache die ich oft verwende, mal als Klasse, mal als einfache Funktion, aber ich könnte auch genauso gut eine Funktion 5 mal copy&pasten, eine Vererbung missbrauchen, oft auch ein Array benutzen usw...Aber Templates sind oft am besten, was einem aber erst auffällt wenn man sie zu seinem Standard C++ Baukasten hinzugefügt hat... sprich wenn man vor einem Problem steht sie beim Lösung überlegen mit einbezieht.