Gibt es Ressourcen, um Probleme zu identifizieren, die am besten mit Vorlagen gelöst werden können?

8

Ich habe mich entschlossen, meine Kenntnisse in der Meta-Programmierung von Vorlagen zu verbessern. Ich kenne die Syntax und die Regeln und habe mit unzähligen Beispielen aus Online-Ressourcen gespielt.

Ich verstehe, wie leistungsfähig Vorlagen sein können und wie viel Optimierung der Kompilierungszeit sie bieten können, aber ich kann immer noch nicht "in Vorlagen denken". Ich kann anscheinend nicht selbst wissen, ob ein bestimmtes Problem mit Vorlagen am besten gelöst werden kann und ob dies möglich ist. wie man dieses Problem an Vorlagen anpasst.

Gibt es eine Art Online-Ressource oder ein Online-Buch, in dem Sie lernen, wie Sie Probleme identifizieren, die am besten mit Vorlagen gelöst werden können, und wie Sie dieses Problem anpassen können?

Saft
quelle
5
Wenn Sie nur einen Hammer haben, sieht alles wie ein Nagel aus ;-) Denken Sie nicht zu viel darüber nach, Vorlagen für alle und alles zu verwenden, zumindest nicht, wenn Sie nicht die nächste Version des C ++ - Standards entwerfen Bibliothek.
Doc Brown
Sie haben Recht, ich werde nicht auf Produktionscode schauen und versuchen, TMP überall anzupassen. heh: p Dies ist nur zum persönlichen Lernen gedacht, weil ich weiß, wie leistungsfähig sie sein können und ich liebe, wie einige großartige C ++ - Programmierer (wie STL, die arbeiten) auf MS) ​​kann TMP so schnell auf ein bestimmtes Problem anwenden und es sieht so toll aus. STL hat ein paar Videos auf Kanal 9, die mich wirklich beeindruckt haben von TMP, deshalb möchte ich mehr erfahren.
sap

Antworten:

8

Bücher:

Modernes C ++ - Design

C ++ - Vorlagen-Metaprogrammierung

Mit Rekursion und funktionaler Programmierung vertraut zu sein, ist ein großes Plus, da dies bei viel tmp eine Rolle spielt. Es ist vollständig und so ist im Wesentlichen alles möglich, obwohl es normalerweise darauf hinausläuft, reine Funktionen auf Konstanten anzuwenden oder Typen aus anderen Typen zu generieren.

Achtung: tmp ist ein hässliches Monster, das schönen Code in Spaghetti verwandelt. Je mehr Sie es verwenden, desto weniger wird Ihnen C ++ gefallen. Es ist eine böse Sache.

Pubby
quelle
1
+1 für "tmp ist ein hässliches Monster". C ++ ist in einigen Dingen gut, genau wie jede andere Sprache. Aber Metaprogrammierung gehört nicht dazu.
Jon Purdy
"Modernes C ++ - Design" ist ein Klassiker, aber im IIRC geht es mehr darum, Dinge mit cleveren Vorlagentricks zu implementieren, als zu entscheiden, was als Vorlage implementiert werden soll. Das Nein. Ein Prinzip dafür ist wahrscheinlich "nicht" - die häufigsten Gründe für die Notwendigkeit einer Vorlage werden bereits von der Standardbibliothek (insbesondere C ++ 11), Boost und anderen bereits vorhandenen Bibliotheken behandelt eigene ist nicht wirklich eine alltägliche Sache.
Steve314
C ++ Template Metaprogramming ist nur das Benutzerhandbuch eines Teils von Boost. Sie lernen nicht viel über die Auswahl einer Anwendung, für die sie relevant ist, und darüber, wie ähnliche Dinge in C ++ ausgeführt werden.
AProgrammer
6

Lernen Sie Haskell oder eine andere reine Funktionssprache (Lisp, Scheme, OCaml, um nur einige zu nennen, mehr finden Sie auf Wikipedia ).

In Anbetracht Haskell, können Sie mehr Informationen über sie die metaprogramming Einrichtungen finden sich hier .

Die Vorlagenprogrammierung folgt weitgehend denselben Regeln.

Macke
quelle
1
Beachten Sie, dass Haskell über ein eigenes Template-System verfügt: Template Haskell.
2
@ MattFenwick: Ja. Und im Gegensatz zu C ++ - Vorlagen ist es immer noch Haskell. :)
Macke
Ich habe seit dem Studium am College nicht mehr mit einer funktionalen Sprache gearbeitet. nicht, dass ich es nicht mag, es hatte einfach nie eine Chance auf Arbeit und wenn ich meine Freizeit damit verbringen muss, zu programmieren oder mehr zu lernen, lerne ich lieber etwas anderes (wie TMP!) :)
SAP
@sap: Nun, Sie müssen in die gleiche Denkweise kommen ...
Macke
@sap: Eigentlich könnte Scheme eine großartige Sprache sein, um sich an die Metaprogrammierung zur Kompilierungszeit zu gewöhnen. Das Makrosystem ist äußerst leistungsfähig und elegant und erzielt einen ähnlichen Effekt wie die Vorlagen von C ++ (ich glaube, ich habe C ++ jedoch nicht zu oft verwendet).
Tikhon Jelvis
2

Nur weil Sie etwas mit Vorlagen tun können, heißt das nicht, dass Sie es tun sollten. In der Praxis ist es wahrscheinlich besser, sie nicht zu verwenden, es sei denn, Sie entwerfen beim Entwerfen, dass dies ein großartiger Job für Vorlagen ist. Wenn Sie zu viel in Vorlagen denken, erstellen Sie einfach wahnsinnig abstrahierten Code, der genauso schlecht ist wie eine einzelne Riesenfunktion.

Ryathal
quelle
danke für die antwort, ja ich verstehe das, ich will nur lernen :)
sap
Ich stimme dem oben Gesagten zu. In den Fällen, in denen ich Vorlagen verwendet habe, war dies normalerweise das Ergebnis der Überarbeitung des vorhandenen Codes. Sobald Sie Ihren Originalcode auf neue Weise verwenden, wird die Vorlage deutlicher als Verbesserung des Originals angezeigt. Es ist schwieriger zu sagen, ob eine Vorlage nützlich ist, wenn das Design vor bekannten Anwendungsfällen ausgeführt wird.
Sam Goldberg
2

Beachten Sie, dass Vorlagen die beste Lösung sind. Ich habe meine eigene in den letzten 5 Jahren nur einmal definiert, und meine Kollegen, die diesen Code überprüft haben, haben dies nie getan. Die Fälle, in denen Vorlagen sehr sinnvoll sind, wurden größtenteils bereits in Standardbibliotheken implementiert.

Bei der generischen Programmierung sollten Sie darauf achten, dass Sie Funktionen kopieren und einfügen, um nur geringfügige Änderungen vorzunehmen, z. B. an Konstanten oder Typen, und keine saubere Methode finden, um Vererbungs- oder Funktionsparameter zu verwenden, um Wiederholungen zu vermeiden du selber.

Eine ziemlich häufige Art und Weise, wie Vorlagen verwendet werden, ist die Typensicherheit, wenn Sie Typen haben, die sich gleich verhalten, aber aus irgendeinem Grund nicht versehentlich verwechselt werden sollen.

Bei der Berechnung der Kompilierungszeit mithilfe von Vorlagen sollten Sie auf ressourcenintensive Berechnungen achten, bei denen alle Eingaben zur Kompilierungszeit bekannt sind, bei denen jedoch unterschiedliche konstante Eingaben an verschiedenen Stellen im Code verwendet werden. Beachten Sie jedoch, dass dies Ihre Kompilierungen jedes Mal verlangsamt. Daher ist es häufig vorzuziehen, die Ergebnisse nur manuell hart zu codieren, wenn sie sich nicht sehr oft ändern.

Einige Befürworter verwenden Vorlagen für Mikrooptimierungen wie das Vermeiden der Suche nach virtuellen Tabellen mithilfe statischen Polymorphismus oder zum Abrollen von Schleifen. Meiner Meinung nach überwiegt die Komplexität jedoch normalerweise die Leistungssteigerung, es sei denn, Ihr Code ist sehr leistungskritisch.

Karl Bielefeldt
quelle
Vielen Dank für die Antwort. Denken Sie an diese Punkte. Ich weiß, dass ich es nicht für alles verwenden kann (wie jemand zuvor sagte, ich kann nicht anfangen, alles als "Nagel" zu sehen) und wenn ich richtig verstehe, dass TMP sich in der Bibliotheksentwicklung auszeichnet (das gesamte C ++ tut es), mache ich dies nur, um zu lernen und NICHT um es in jedem Produktionscode anzuwenden, den ich von nun an erstelle. und wow nur einmal in 5 Jahren? Ich denke, das zeigt, wie selten TMP Code WIRKLICH verbessern kann.
SAP
2

Grundsätzlich gibt es mehrere gute Gründe, Vorlagen zu verwenden:

  1. Sie haben eine Funktion oder eine Klasse, die für verschiedene Typen dieselbe Funktionalität hat. Ein gutes Beispiel für die Verwendung guter Vorlagen ist die Boost-Bibliothek
  2. Sie möchten statischen Polymorphismus verwenden und Kompilierungsfehler anstelle von Laufzeitfehlern erhalten
  3. Sie möchten ein bestimmtes Verhalten in Abhängigkeit von einigen statischen Parametern erhalten. Zum Beispiel bietet boost :: type_traits sehr gute Beispiele.
BЈовић
quelle
Vielen Dank! Ich habe schon früher Typmerkmale verwendet, wirklich cooles Zeug! Ist enable_if auch ein Typmerkmal? oder nur eine SFINAE "Bedingung"? weil ich es schon einmal benutzt habe (bei der Codeüberprüfung) und es so mächtig schien, aber ich kann es nicht auf verschiedene Probleme anwenden.
SAP
@sap Es ist ein Typmerkmal, das mit SFINAE implementiert werden kann.
BЈовић
1

Sie sollten sich unbedingt Vorlagen in C ++ ansehen! Dies wird Ihnen sehr helfen, Themen wie Entwurfsmuster und generische Programmierung zu verstehen. Vergleichen Sie sie mit dem, was andere Sprachen Ihnen bieten. Genau genommen sollten Sie Vorlagen verwenden, insbesondere in den folgenden Szenarien:

  1. Generalisierung und Wiederverwendung von Code
  2. Flexibilität
  3. Zeit- und Budgetbeschränkungen
  4. Mangel an Fachwissen für eine bestimmte Aufgabe

Hier ist eine gute Online-Ressource für Sie: http://en.wikipedia.org/wiki/Generic_programming#Templates_in_C.2B.2B

Maxood
quelle
Ich weiß, wofür sie verwendet werden können, um nicht nur dieses Wissen auf gegebene Probleme anzuwenden, sondern auch eine gute Lektüre, danke :)
SAP
1

Ein einfacher Indikator dafür, wann eine Vorlage Ihren Code verbessern würde, ist, wenn Sie feststellen, dass Ihr Code häufig erfordert, dass Sie ein Objekt in einen anderen Typ umwandeln. Ein Beispiel, das ich in meinem eigenen Java-Code gefunden habe und das mich dazu veranlasste, eine vorhandene Methodensignatur in eine Vorlage zu konvertieren:

    public MsgBase getLastSentMessage(Class<? extends MsgBase> msgBaseClass)

Mein Kundencode sah immer so aus:

    OrderResponse response = (OrderResponse) getLastSentMessage(OrderResponse.class);

und wann immer ich diese Methode verwendete, musste ich das Ergebnis in die richtige Unterklasse des MsgBase-Typs umwandeln. Die verbesserte Methodensignatur war:

    public <T extends MsgBase> T getLastSentMessage(Class<T> clazz)

Jetzt war der Client-Code:

     OrderResponse response = getLastSentMessage(OrderResponse.class);

Zusammenfassend lässt sich sagen, dass Sie möglicherweise einen guten Fall haben, in dem eine Vorlage Ihren Code bereinigt, wenn Sie viel Casting durchführen, was unnötig erscheint.

Update: Ein besserer Weg, um die obige Aussage zu verallgemeinern:

Wenn Ihre Quellklasse von Objekten vieler verschiedener Typen verwendet wird und die Quellklasse mit diesen Typen auf einer höheren (abstrakteren) Ebene interagieren kann, Ihre Clientklassen jedoch mit bestimmten Untertypen interagieren möchten, ist dies bei der Verwendung von Vorlagen der Fall . (Container / List-Klassen sind das bekannte Beispiel).

Sam Goldberg
quelle
Das ist sehr interessant und ich habe nie daran gedacht, TMP so anzuwenden. Es zeigt nur, dass ich es wirklich besser lernen und mehr üben muss.
SAP
Ich versuche immer noch, die Abstimmungen hier herauszufinden. Ich beantwortete die Frage direkt und lieferte ein konkretes Beispiel dafür, wann eine Vorlage aus einem Refactoring entsteht. Also, was war los?
Sam Goldberg
0

Erst heute habe ich Vorlagen verwendet, um eine Finite-State-Maschine zu implementieren, um einige Eingaben zu lexen. Ausdrucksvorlagen sind äußerst leistungsfähige Werkzeuge für die Implementierung solcher Codekonzepte. Sie laufen wie handoptimiertes C ++ und sind unglaublich schnell, aber sehr allgemein und sehr einfach zu schreiben.

Im Allgemeinen sind Vorlagen bei der Implementierung generischer Algorithmen am sinnvollsten. Wenn Sie keinen generischen Algorithmus implementieren, sind diese nicht so sinnvoll.

DeadMG
quelle
0

Vorlagen werden am häufigsten wie folgt verwendet:

std::vector<int> vec;
std::map<int, float> mymap;

Das nächste häufige Beispiel ist:

template<class T>
class MyArray {
public:
   virtual T get(int i) const=0;
};

Zusammen mit dieser Art der Nutzung:

class ArrayImpl : public MyArray<float> {
public:
     float get(int i) const { }
};

Dieser zeigte einen wichtigen Teil der Vorlagen, nämlich die Typersetzung - T wird an beiden Stellen, an denen er verwendet wird, durch den Float-Typ ersetzt.

tp1
quelle