Kurze Antwort: Sie mischen Konzepte vor der Kompilierung und Konzepte zur Kompilierungszeit , deren Zweck Ähnlichkeiten aufweist. Schnittstellen (abstrakte Klassen und die gesamte Implementierung des Objektorientierungsparadigmas) werden zur Kompilierungszeit erzwungen . Konzepte sind die gleiche Idee, aber im Kontext der generischen Programmierung, die in C ++ VOR der Kompilierungszeit auftritt . Wir haben das letzte Feature noch nicht.
Aber lassen Sie mich von Anfang an erklären.
Lange Antwort:
Tatsächlich sind Konzepte nur eine Sprachverbesserung und "für den Programmierer einfacher" für etwas, das bereits in der Sprache vorhanden ist und das man als "Ententypisierung" bezeichnen könnte.
Wenn Sie einen Typ an eine Vorlagenfunktion übergeben, dh eine generische Funktion, aus der der Compiler beim Aufruf echten (Inline-) Code generiert, muss dieser Typ einige Eigenschaften (Merkmale?) Haben, die im Vorlagencode verwendet werden. Es ist also die Idee, Enten zu tippen, ABER alles wird zur Kompilierungszeit generiert und ausgeführt .
Was passiert, wenn der Typ nicht die erforderlichen Eigenschaften hat?
Nun, der Compiler wird wissen, dass es erst dann ein Problem gibt, wenn der aus der Vorlage generierte Code kompiliert wurde und fehlschlägt. Das bedeutet, dass der Fehler, der generiert wird, ein Fehler im Vorlagencode ist, der dem Programmierer als sein Fehler angezeigt wird. Außerdem enthält der Fehler aufgrund der Metainformationen, die bei der Generierung von Vorlagencode bereitgestellt werden, unzählige Informationen, um zu wissen, um welche Instanziierung der Vorlage es sich handelt.
Einige Probleme damit: Erstens ist Vorlagencode meistens Bibliothekscode, und die meisten Programmierer sind Benutzer von Bibliothekscode, keine Verfasser von Bibliothekscode. Das bedeutet, dass diese Art von kryptischem Fehler wirklich schwer zu verstehen ist, wenn Sie nicht verstehen, wie die Bibliothek geschrieben ist (nicht nur das Design, wie sie wirklich implementiert ist). Das zweite Problem ist, dass selbst wenn der Programmierer den Vorlagencode geschrieben hat, die Fehlerursachen möglicherweise immer noch unklar sind, da der Compiler erkennen kann, dass ein Problem zu spät vorliegt: Wenn der generierte Code kompiliert wird. Wenn das Problem mit den relativen Typ Eigenschaften, dann sollte es sie prüft , noch bevor Sie den Code zu generieren.
Dies ist es, was Konzepte zulassen (und für die sie entwickelt wurden): Damit der (generische Code-) Programmierer die Eigenschaften von Typen angeben kann, die als Vorlagenparameter übergeben werden, und der Compiler dann explizite Fehler angeben kann, falls die bereitgestellten Typen die Anforderungen nicht erfüllen Anforderungen.
Sobald die Prüfung erfolgreich ist, wird der Code aus der Vorlage generiert und dann mit Sicherheit erfolgreich kompiliert.
Die gesamte Konzeptprüfung erfolgt ausschließlich vor der Kompilierungszeit . Es überprüft die Typen selbst und nicht die Objekttypen . Vor der Kompilierungszeit ist kein Objekt vorhanden.
Nun zu "Schnittstellen".
Wenn Sie einen abstrakten oder virtuellen Basistyp erstellen, erlauben Sie Code, damit Objekte der untergeordneten Typen zu bearbeiten, ohne deren tatsächliche Implementierung zu kennen. Um dies zu erzwingen, macht der Basistyp Mitglieder verfügbar, die virtuell sind und möglicherweise von den untergeordneten Typen überlastet werden (oder müssen).
Dies bedeutet, dass der Compiler zur Kompilierungszeit überprüfen kann, ob alle Objekte, die an eine Funktion übergeben werden, die einen Verweis auf die Basisklasse erfordert, 1. einem der untergeordneten Typen der Basisklasse angehören müssen, 2. dass der untergeordnete Typ Implementierungen von haben muss ggf. in Basisklassen deklarierte virtuelle reine Funktionen.
So zum Zeitpunkt der Kompilierung , prüft der Compiler die Schnittstellen des Objekts Typen und Bericht erstellen , wenn etwas fehlt.
Es ist die gleiche Idee wie bei Concepts, aber es kommt zu spät , wie in der Concept-Beschreibung angegeben. Es tritt zur Kompilierungszeit auf. Wir befinden uns nicht im generischen Code (Vorlagencode), sondern erst, nachdem er verarbeitet wurde, und es ist bereits zu spät, um zu überprüfen, ob die Typen generische Anforderungen erfüllen, die von virtuellen Basisklassen nicht verfügbar gemacht werden können. Tatsächlich existiert die gesamte Implementierung des Objektorientierungsparadigmas in C ++ nicht einmal, wenn der Vorlagencode verarbeitet wird. Es gibt (noch) keine Objekte. Das ist
Klassen beschreiben Einschränkungen für Objekte, die zum Überprüfen der Anforderungen für Funktionen verwendet werden sollen, die diese Objekte bearbeiten. Konzepte beschreiben Einschränkungen für Typen (einschließlich Klassen), die zum Überprüfen der Anforderungen für generischen Code verwendet werden sollen, um aus diesen Typen und der Kombination aus generischem Code echten Code zu generieren.
Es handelt sich also wieder um dieselbe "Überprüfung der geistigen Gesundheit", jedoch in einer anderen Sprachebene, dh um Vorlagen. Vorlagen sind eine vollständige (vollständig) Sprache, die Metaprogrammierung und Programmiertypen ermöglicht, noch bevor sie im kompilierten Code erscheinen. Es ist ein bisschen wie das Schreiben von Skripten für den Compiler. Angenommen, Sie können ein Skript erstellen. Klassen sind nur vom Skript manipulierte Werte. Derzeit gibt es keine andere Möglichkeit, Einschränkungen für diese Werte zu überprüfen, als das Skript auf nicht offensichtliche Weise zum Absturz zu bringen. Konzepte sind genau das: Geben Sie die Eingabe für diese Werte ein (die im generierten Code Typen sind). Ich bin mir nicht sicher, ob ich klar bin ...
Ein weiterer wirklich wichtiger Unterschied zwischen virtuellen Basisklassen und Konzepten besteht darin, dass die erste eine starke Beziehung zwischen Typen erzwingt und sie "blutgebunden" macht. Während die Metaprogrammierung von Vorlagen das "Enten-Tippen" ermöglicht, erlauben Konzepte nur, die Anforderungen klarer zu machen.