Aus verschiedenen Vergleichen zwischen C ++ - Vorlagen und C # / Java-Generika wie diesem
Ich habe die Vorstellung, dass C ++ - Vorlagen durch eine Art Vorverarbeitung (Ersetzen von einfachem Text vor dem Parsen) implementiert und nicht kompiliert werden. Da die Typüberprüfung in C ++ - Vorlagen C-Makros ähnelt. Ich meine, wenn es einige Fehler gibt, handelt es sich um Fehler aus dem generierten Code nach der Verarbeitung von Codeblöcken mit Vorlagen, nicht aus den Vorlagen selbst. Mit anderen Worten, sie sind nur eine Art obere Version von Makros in C.
Dann fand ich einige andere Fakten, die dies unterstützen.
Ich dachte, wenn C ++ - Vorlagen durch Vorverarbeitung implementiert werden, wird es Probleme mit der dynamischen Verknüpfung (mit DLL) geben. Und ein schnelles googeln unterstützte dies.
Ein weiterer Punkt ist, dass Integer-Konstanten als Argumente an die Vorlagen übergeben werden können. Und es unterstützt sogar eine Art Rekursion. Diese Rekursion ist jedoch nicht im kompilierten Assembly- / Maschinencode enthalten. Die Rekursionssache wird in der Kompilierungszeit verwaltet, indem für jeden rekursiven Aufruf eine Funktion generiert wird und somit eine größere, aber schneller ausführbare Binärdatei vorliegt.
Im Gegensatz zu C-Makros verfügt es über einige überlegene Fähigkeiten. Aber ist C ++ Template nicht mit einer Art Vorverarbeitung implementiert? Wie ist dies in verschiedenen C ++ - Compilern implementiert?
Antworten:
C ++ - Vorlagen sind eine Art von Lisp-Makros (oder sogar Scheme-Makros). Es ist eine Turing-vollständige Sprache, die in der Kompilierungszeit ausgewertet wird, jedoch stark eingeschränkt ist, da von dieser Sprache kein Zugriff auf die zugrunde liegende C ++ - Umgebung besteht. Ja, C ++ - Vorlagen können als eine Form der Vorverarbeitung angesehen werden, mit einer sehr begrenzten Interaktion mit dem generierten Code.
quelle
Der wahrscheinlich größte Unterschied besteht darin, dass C-Makros in der Vorverarbeitungsphase erweitert werden, bevor eine andere Kompilierung durchgeführt wird, während C ++ - Vorlagen Teil der Kompilierung sind. Dies bedeutet, dass C ++ - Vorlagen unter anderem typensensitiv und bereichsspezifisch sind und keine einfache Textsubstitution darstellen. Sie können zu echten Funktionen kompiliert werden und vermeiden daher die meisten Probleme, die Makros haben. Wenn Sie typbewusst arbeiten, können Sie allgemeine oder spezielle
swap
Funktionen verwenden. Beispielsweise können Sie problemlos eine Vorlagenfunktion bereitstellen und Spezialisierungen schreiben, die auch dann gut funktionieren, wenn die Objekte den Heapspeicher verwalten.Daher gilt: C ++ - Vorlagen werden nicht im selben Sinne wie Makros vorverarbeitet, sie sind keine Art von C-Makro, und es ist unmöglich, C-Makros zum Duplizieren der Aufgaben von Vorlagen zu verwenden.
Vorlagen befinden sich in Header-Dateien, nicht in verknüpften Bibliotheken, true, aber wenn Sie eine DLL-Datei bereitstellen, stellen Sie vermutlich auch eine Header-Datei zur Verfügung.
quelle
export
implementiert. Ich weiß, dass es für Funktionen funktioniert, aber ich bezweifle, dass es für Klassen funktioniert: Wie würden Sie ihre Größe kennen?Ist es wichtig, wie sie implementiert werden? Die frühen C ++ - Compiler waren nur Pre-Prozessoren, die den Code an den AC-Compiler weitergaben. Dies bedeutet nicht, dass C ++ nur ein verherrlichtes Makro ist.
Vorlagen machen Makros überflüssig, da sie eine sicherere, effizientere und spezifischere Methode zur Implementierung von Code für mehrere Typen bieten (auch wenn ich das nicht für richtig halte).
Es gibt eine Vielzahl von Möglichkeiten, Templatetypcode in c zu erstellen, von denen keine sehr hilfreich ist, wenn Sie über einfache Typen hinausgehen.
quelle
Es gibt einige Unterschiede; Vorlagen können beispielsweise verwendet werden, um bei Bedarf eine Funktionsüberladung zu instanziieren, während Sie bei Makros das Makro einmal für jede mögliche Überladung erweitern müssen, um es für den Compiler sichtbar zu machen von nicht verwendetem Code.
Ein weiterer Unterschied besteht darin, dass Vorlagen Namespaces berücksichtigen.
quelle
IMHO, C ++ - Vorlagen und C-Makros sollten zwei völlig unterschiedliche Probleme lösen. Die ursprüngliche C ++ - Standardvorlagenbibliothek war ein Mechanismus, um Containerklassen (Arrays, verknüpfte Listen usw.) sauber von den allgemeinen Funktionen zu entkoppeln, die auf sie angewendet werden (wie Sortieren und Verketten). Abstrakte Darstellungen effizienter Algorithmen und Datenstrukturen führen zu einem aussagekräftigeren Code, da deutlich weniger geraten wurde, wie eine Funktion, die mit einem bestimmten Datenelement arbeitet, am besten implementiert werden kann. Die C-Makros entsprachen weitaus mehr dem, was man normalerweise in Lisp-Makros sieht, da sie eine Möglichkeit bieten, die Sprache mit Inline-Code zu "erweitern". Das Coole ist, dass die C ++ Standard Library die Funktionalität von Vorlagen erweitert hat, um die große Mehrheit dessen abzudecken, wofür wir #define in C verwenden.
quelle