Concepts library (since C++20)
Die Concepts-Bibliothek bietet Definitionen von grundlegenden Bibliothekskonzepten, die zur Compile-zeit-Validierung von Template-Argumenten und zur Funktionsauswahl basierend auf Eigenschaften von Typen verwendet werden können. Diese Konzepte bilden eine Grundlage für equational reasoning in Programmen.
Die meisten Konzepte in der Standardbibliothek stellen sowohl syntaktische als auch semantische Anforderungen. Man sagt, dass ein Standardkonzept erfüllt ist, wenn seine syntaktischen Anforderungen erfüllt sind, und dass es modelliert wird, wenn es erfüllt ist und seine semantischen Anforderungen (falls vorhanden) ebenfalls erfüllt sind.
Im Allgemeinen kann der Compiler nur die syntaktischen Anforderungen überprüfen. Wenn die Gültigkeit oder Bedeutung eines Programms davon abhängt, ob eine Folge von Template-Argumenten ein Konzept modelliert, und das Konzept erfüllt, aber nicht modelliert wird, oder wenn eine semantische Anforderung am Verwendungsort nicht erfüllt ist, ist das Programm fehlerhaft, no diagnostic required .
Inhaltsverzeichnis |
Gleichheitserhaltung
Ein Ausdruck ist gleichheitserhaltend wenn er bei gleichen Eingaben gleiche Ausgaben liefert, wobei
- die Eingaben bestehen aus seinen Operanden (müssen den Ausdruck nicht unbedingt semantisch gültig machen), und
- die Ausgaben bestehen aus seinem Ergebnis und allen Änderungen an den Operanden durch den Ausdruck, falls vorhanden
wobei, zur Vereinfachung der Formulierung, seine "Operanden" sich auf seine größten Teilausdrücke beziehen, die aus einem id-expression oder Aufrufen von std::move , std::forward und std::declval bestehen.
Die CV-Qualifikation und der Wertkategorie jedes Operanden werden bestimmt, indem angenommen wird, dass jeder Template-Typparameter in seinem Typ einen CV-unqualifizierten vollständigen Nicht-Array-Objekttyp bezeichnet.
Jeder Ausdruck, der gleichheitserhaltend sein muss, muss darüber hinaus stabil sein, das heißt, zwei Auswertungen desselben mit denselben Eingabeobjekten müssen gleiche Ausgaben ergeben, ohne dass zwischenzeitlich ausdrücklich Änderungen an diesen Eingabeobjekten vorgenommen wurden.
Sofern nicht anders angegeben, muss jeder Ausdruck, der in einem requires expression der Standardbibliothek-Konzepte verwendet wird, gleichheitserhaltend sein, und die Auswertung des Ausdrucks darf nur seine nicht-konstanten Operanden modifizieren. Operanden, die konstant sind, dürfen nicht modifiziert werden.
In der Standardbibliothek dürfen die folgenden Konzepte nicht-gleichheitserhaltende requires -Ausdrücke haben:
Implizite Ausdrucksvarianten
Ein requires -Ausdruck , der einen Ausdruck verwendet, der für einen konstanten Lvalue-Operanden nicht-modifizierend ist, erfordert implizit auch zusätzliche Varianten dieses Ausdrucks, die einen nicht-konstanten Lvalue oder (möglicherweise konstanten) Rvalue für den gegebenen Operanden akzeptieren, es sei denn, eine solche Ausdrucksvariante wird explizit mit abweichender Semantik gefordert.
Diese impliziten Ausdrucksvarianten müssen die gleichen semantischen Anforderungen erfüllen wie der deklarierte Ausdruck. In welchem Umfang eine Implementierung die Syntax der Varianten überprüft, ist nicht spezifiziert.
template<class T> concept C = requires(T a, T b, const T c, const T d) { c == d; // Ausdruck #1: verändert die Operanden nicht a = std::move(b); // Ausdruck #2: verändert beide Operanden a = c; // Ausdruck #3: verändert den linken Operanden `a` }; // Ausdruck #1 erfordert implizit zusätzliche Ausdrucksvarianten, // die die Anforderungen für c == d erfüllen (einschließlich Nicht-Veränderung), // als ob die folgenden Ausdrücke ebenfalls deklariert worden wären: // ------ const == const ------- ------ const == non-const --- // c == b; // c == std::move(d); c == std::move(b); // std::move(c) == d; std::move(c) == b; // std::move(c) == std::move(d); std::move(c) == std::move(b); // -- non-const == const ------- -- non-const == non-const --- // a == d; a == b; // a == std::move(d); a == std::move(b); // std::move(a) == d; std::move(a) == b; // std::move(a) == std::move(d); std::move(a) == std::move(b); // Ausdruck #3 erfordert implizit zusätzliche Ausdrucksvarianten, // die die Anforderungen für a = c erfüllen // (einschließlich Nicht-Veränderung des zweiten Operanden), // als ob die Ausdrücke a = b (Non-Constant-Lvalue-Variante) // und a = std::move(c) (Const-Rvalue-Variante) deklariert worden wären. // Hinweis: Da Ausdruck #2 bereits die Non-Constant-Rvalue-Variante // (a == std::move(b)) explizit erfordert, erfordert Ausdruck #3 sie nicht mehr implizit. // Der Typ T erfüllt die explizit angegebenen syntaktischen Anforderungen des // Konzepts C oben, erfüllt jedoch nicht die zusätzlichen impliziten Anforderungen // (d.h. T erfüllt C, modelliert es aber nicht): // ein Programm, das C<T> erfordert, ist fehlerhaft (keine Diagnose erforderlich). struct T { bool operator==(const T&) const { return true; } bool operator==(T&) = delete; };
Standardbibliothek-Konzepte
|
Definiert im namespace
std
|
|
Kernsprachkonzepte |
|
|
Definiert im Header
<concepts>
|
|
|
(C++20)
|
spezifiziert, dass ein Typ identisch mit einem anderen Typ ist
(Konzept) |
|
(C++20)
|
gibt an, dass ein Typ von einem anderen Typ abgeleitet ist
(Konzept) |
|
(C++20)
|
spezifiziert, dass ein Typ implizit in einen anderen Typ konvertierbar ist
(Konzept) |
|
(C++20)
|
spezifiziert, dass zwei Typen einen gemeinsamen Referenztyp teilen
(Konzept) |
|
(C++20)
|
spezifiziert, dass zwei Typen einen gemeinsamen Typ teilen
(Konzept) |
|
(C++20)
|
gibt an, dass ein Typ ein integraler Typ ist
(Konzept) |
|
(C++20)
|
spezifiziert, dass ein Typ ein vorzeichenbehafteter Ganzzahltyp ist
(Konzept) |
|
(C++20)
|
spezifiziert, dass ein Typ ein integraler Typ ist, der vorzeichenlos ist
(Konzept) |
|
(C++20)
|
gibt an, dass ein Typ ein Gleitkommatyp ist
(Konzept) |
|
(C++20)
|
spezifiziert, dass ein Typ von einem anderen Typ zuweisbar ist
(Konzept) |
|
(C++20)
|
gibt an, dass ein Typ ausgetauscht werden kann oder dass zwei Typen miteinander ausgetauscht werden können
(Konzept) |
|
(C++20)
|
spezifiziert, dass ein Objekt des Typs zerstört werden kann
(Konzept) |
|
(C++20)
|
gibt an, dass eine Variable des Typs aus oder an eine Menge von Argumenttypen konstruiert oder gebunden werden kann
(Konzept) |
|
(C++20)
|
spezifiziert, dass ein Objekt eines Typs standardmäßig konstruiert werden kann
(Konzept) |
|
(C++20)
|
gibt an, dass ein Objekt eines Typs per Move-Konstruktion erstellt werden kann
(Konzept) |
|
(C++20)
|
spezifiziert, dass ein Objekt eines Typs kopierkonstruiert und bewegekonstruiert werden kann
(Konzept) |
Vergleichskonzepte |
|
|
Definiert im Header
<concepts>
|
|
|
(C++20)
|
spezifiziert, dass ein Typ in booleschen Kontexten verwendet werden kann
( exposition-only concept* ) |
|
spezifiziert, dass der Operator
==
eine Äquivalenzrelation ist
(Konzept) |
|
|
spezifiziert, dass die Vergleichsoperatoren des Typs eine Totalordnung ergeben
(Konzept) |
|
|
Definiert im Header
<compare>
|
|
|
spezifiziert, dass der Operator
<=>
konsistente Ergebnisse für gegebene Typen liefert
(Konzept) |
|
Objektkonzepte |
|
|
Definiert im Header
<concepts>
|
|
|
(C++20)
|
spezifiziert, dass ein Objekt eines Typs verschoben und ausgetauscht werden kann
(Konzept) |
|
(C++20)
|
spezifiziert, dass ein Objekt eines Typs kopiert, verschoben und ausgetauscht werden kann
(Konzept) |
|
(C++20)
|
spezifiziert, dass ein Objekt eines Typs kopiert, verschoben, ausgetauscht und standardkonstruiert werden kann
(Konzept) |
|
(C++20)
|
spezifiziert, dass ein Typ regulär ist, das heißt, er ist sowohl
semiregular
als auch
equality_comparable
(Konzept) |
Callable-Konzepte |
|
|
Definiert im Header
<concepts>
|
|
|
(C++20)
|
gibt an, dass ein aufrufbarer Typ mit einem gegebenen Satz von Argumenttypen aufgerufen werden kann
(Konzept) |
|
(C++20)
|
spezifiziert, dass ein aufrufbarer Typ ein boolesches Prädikat ist
(Konzept) |
|
(C++20)
|
spezifiziert, dass ein aufrufbarer Typ eine binäre Relation ist
(Konzept) |
|
(C++20)
|
spezifiziert, dass eine
relation
eine Äquivalenzrelation definiert
(Konzept) |
|
(C++20)
|
spezifiziert, dass eine
relation
eine strikte schwache Ordnung erzwingt
(Konzept) |
Weitere Konzepte finden sich in der Iteratoren-Bibliothek , der Algorithmen-Bibliothek und der Ranges-Bibliothek .