Concepts library (since C++20)
La bibliothèque de concepts fournit des définitions de concepts fondamentaux de la bibliothèque qui peuvent être utilisés pour effectuer une validation à la compilation des arguments de template et réaliser une dispatch de fonction basée sur les propriétés des types. Ces concepts fournissent une base pour le raisonnement équationnel dans les programmes.
La plupart des concepts dans la bibliothèque standard imposent à la fois des exigences syntaxiques et sémantiques. On dit qu'un concept standard est satisfait si ses exigences syntaxiques sont remplies, et est modélisé s'il est satisfait et que ses exigences sémantiques (le cas échéant) sont également remplies.
En général, seules les exigences syntaxiques peuvent être vérifiées par le compilateur. Si la validité ou la signification d'un programme dépend du fait qu'une séquence d'arguments de modèle modélise un concept, et que le concept est satisfait mais non modélisé, ou si une exigence sémantique n'est pas respectée au point d'utilisation, le programme est mal formé, aucun diagnostic requis .
Table des matières |
Préservation de l'égalité
Une expression est equality-preserving si elle produit des sorties égales pour des entrées égales, où
- les entrées comprennent ses opérandes (ne rendant pas nécessairement l'expression sémantiquement valide), et
- les sorties comprennent son résultat et toutes les modifications apportées aux opérandes par l'expression, le cas échéant
où, par commodité de formulation, ses « opérandes » désignent ses plus grandes sous-expressions constituées d'une id-expression ou d'appels à std::move , std::forward , et std::declval .
La qualification cv et la catégorie de valeur de chaque opérande sont déterminées en supposant que chaque paramètre de type template dans son type dénote un type objet complet non-tableau non qualifié cv.
Toute expression devant être préservatrice d'égalité doit en outre être stable, c'est-à-dire que deux évaluations de celle-ci avec les mêmes objets d'entrée doivent produire des sorties égales sans aucune modification explicite intercalée de ces objets d'entrée.
Sauf indication contraire, toute expression utilisée dans une requires expression des concepts de la bibliothèque standard doit préserver l'égalité, et l'évaluation de l'expression ne peut modifier que ses opérandes non constants. Les opérandes constants ne doivent pas être modifiés.
Dans la bibliothèque standard, les concepts suivants sont autorisés à avoir des expressions requires non préservant l'égalité :
Variations d'expression implicites
Une requires expression qui utilise une expression non modifiante pour un opérande constant lvalue requiert également implicitement des variations supplémentaires de cette expression qui acceptent un lvalue non constant ou un rvalue (éventuellement constant) pour l'opérande donné, sauf si une telle variation d'expression est explicitement requise avec une sémantique différente.
Ces variations d'expression implicites doivent satisfaire aux mêmes exigences sémantiques que l'expression déclarée. La mesure dans laquelle une implémentation valide la syntaxe des variations n'est pas spécifiée.
template<class T> concept C = requires(T a, T b, const T c, const T d) { c == d; // expression #1: ne modifie pas les opérandes a = std::move(b); // expression #2: modifie les deux opérandes a = c; // expression #3: modifie l'opérande gauche `a` }; // L'expression #1 requiert implicitement des variations d'expression supplémentaires // qui satisfont aux exigences pour c == d (incluant la non-modification), // comme si les expressions suivantes avaient également été déclarées : // ------ 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); // L'expression #3 requiert implicitement des variations d'expression supplémentaires // qui satisfont aux exigences pour a = c // (incluant la non-modification du second opérande), // comme si les expressions a = b (variation lvalue non constante) // et a = std::move(c) (variation rvalue constante) avaient été déclarées. // Note : Puisque l'expression #2 requiert déjà explicitement la variation rvalue non constante // (a == std::move(b)), l'expression #3 ne la requiert plus implicitement. // Le type T satisfait les exigences syntaxiques explicitement énoncées du // concept C ci-dessus, mais ne satisfait pas les exigences implicites supplémentaires // (c'est-à-dire que T satisfait mais ne modélise pas C) : // un programme requérant C<T> est mal formé (aucun diagnostic requis). struct T { bool operator==(const T&) const { return true; } bool operator==(T&) = delete; };
Concepts de la bibliothèque standard
|
Défini dans l'espace de noms
std
|
|
Concepts fondamentaux du langage |
|
|
Défini dans l'en-tête
<concepts>
|
|
|
(C++20)
|
spécifie qu'un type est identique à un autre type
(concept) |
|
(C++20)
|
spécifie qu'un type est dérivé d'un autre type
(concept) |
|
(C++20)
|
spécifie qu'un type est implicitement convertible en un autre type
(concept) |
|
(C++20)
|
spécifie que deux types partagent un type de référence commun
(concept) |
|
(C++20)
|
spécifie que deux types partagent un type commun
(concept) |
|
(C++20)
|
spécifie qu'un type est un type intégral
(concept) |
|
(C++20)
|
spécifie qu'un type est un type intégral signé
(concept) |
|
(C++20)
|
spécifie qu'un type est un type entier non signé
(concept) |
|
(C++20)
|
spécifie qu'un type est un type à virgule flottante
(concept) |
|
(C++20)
|
spécifie qu'un type peut être assigné à partir d'un autre type
(concept) |
|
(C++20)
|
spécifie qu'un type peut être échangé ou que deux types peuvent être échangés l'un avec l'autre
(concept) |
|
(C++20)
|
spécifie qu'un objet du type peut être détruit
(concept) |
|
(C++20)
|
spécifie qu'une variable du type peut être construite à partir ou liée à un ensemble de types d'arguments
(concept) |
|
(C++20)
|
spécifie qu'un objet d'un type peut être construit par défaut
(concept) |
|
(C++20)
|
spécifie qu'un objet d'un type peut être construit par déplacement
(concept) |
|
(C++20)
|
spécifie qu'un objet d'un type peut être copié par construction et déplacé par construction
(concept) |
Concepts de comparaison |
|
|
Défini dans l'en-tête
<concepts>
|
|
|
(C++20)
|
spécifie qu'un type peut être utilisé dans des contextes booléens
( concept d'exposition uniquement* ) |
|
spécifie que l'opérateur
==
est une relation d'équivalence
(concept) |
|
|
spécifie que les opérateurs de comparaison sur le type produisent un ordre total
(concept) |
|
|
Défini dans l'en-tête
<compare>
|
|
|
spécifie que l'opérateur
<=>
produit un résultat cohérent sur les types donnés
(concept) |
|
Concepts d'objet |
|
|
Défini dans l'en-tête
<concepts>
|
|
|
(C++20)
|
spécifie qu'un objet d'un type peut être déplacé et échangé
(concept) |
|
(C++20)
|
spécifie qu'un objet d'un type peut être copié, déplacé et échangé
(concept) |
|
(C++20)
|
spécifie qu'un objet d'un type peut être copié, déplacé, échangé et construit par défaut
(concept) |
|
(C++20)
|
spécifie qu'un type est régulier, c'est-à-dire qu'il est à la fois
semiregular
et
equality_comparable
(concept) |
Concepts appelables |
|
|
Défini dans l'en-tête
<concepts>
|
|
|
(C++20)
|
spécifie qu'un type appelable peut être invoqué avec un ensemble donné de types d'arguments
(concept) |
|
(C++20)
|
spécifie qu'un type appelable est un prédicat booléen
(concept) |
|
(C++20)
|
spécifie qu'un type appelable est une relation binaire
(concept) |
|
(C++20)
|
spécifie qu'une
relation
impose une relation d'équivalence
(concept) |
|
(C++20)
|
spécifie qu'une
relation
impose un ordre strict faible
(concept) |
Des concepts supplémentaires peuvent être trouvés dans la bibliothèque d'itérateurs , la bibliothèque d'algorithmes , et la bibliothèque de plages .