lang:cpp:concept
Différences
Ci-dessous, les différences entre deux révisions de la page.
Prochaine révision | Révision précédente | ||
lang:cpp:concept [2020/02/05 21:58] – Création root | lang:cpp:concept [2021/11/13 09:04] (Version actuelle) – Ajout de "Restriction" "Fonction template" root | ||
---|---|---|---|
Ligne 5: | Ligne 5: | ||
====Définitions des concepts==== | ====Définitions des concepts==== | ||
- | Contrainte sur un type : | + | * Contrainte sur un type : |
<code cpp> | <code cpp> | ||
Ligne 12: | Ligne 12: | ||
</ | </ | ||
- | Contrainte sur les fonctions : | + | * Contrainte sur les fonctions : |
<code cpp> | <code cpp> | ||
- | // look, this concept requires two types | + | template < |
- | template < | + | // Le type est cv. Donc, il faut utiliser deux paramètres, |
- | concept | + | concept |
{ | { | ||
- | { x * y }; | + | // Le type de retour est facultatif mais conseillé. |
- | { x / y }; | + | { t.area() |
- | { x + y }; | + | { u.mod(f) |
- | { x - y }; | + | // On impose une variable. |
+ | // Elle peut être static / constexpr ou non. | ||
+ | // Il faut la déclarer comme une référence. | ||
+ | | ||
}; | }; | ||
</ | </ | ||
====Application des concepts==== | ====Application des concepts==== | ||
+ | * Vérification qu'une structure respecte un concept | ||
<code cpp> | <code cpp> | ||
- | template <typename | + | struct Rectangle |
- | requires | + | { |
- | void log(T&& | + | consteval float area() const {return 1.;} |
- | { ... } | + | consteval float mod(float f) {return f;} |
+ | static constexpr float varr = 2.f; | ||
+ | }; | ||
+ | static_assert(Shape< | ||
+ | </ | ||
+ | |||
+ | * Forcer un template | ||
+ | |||
+ | <code cpp> | ||
+ | template < | ||
+ | requires | ||
+ | class AllFormes | ||
+ | { | ||
+ | |||
+ | }; | ||
+ | </ | ||
+ | |||
+ | * Cast d'un type vers un concept | ||
+ | |||
+ | <code cpp> | ||
+ | int main() | ||
+ | { | ||
+ | Rectangle a; | ||
+ | Shape auto &b = a; | ||
+ | b.mod(); | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | * Déclaration d'une fonction dont un des paramètres doit respecter un concept | ||
+ | |||
+ | <code cpp> | ||
+ | void foo(const Concept auto&) | ||
+ | {} | ||
+ | </code> | ||
+ | |||
+ | Et cela va générer un symbole pour chaque type. | ||
+ | |||
+ | ====Restriction==== | ||
+ | |||
+ | ===Fonction template=== | ||
+ | |||
+ | Il n'est pas possible de définir un concept avec un template non défini dans le concept. | ||
+ | |||
+ | Exemple: | ||
+ | |||
+ | <code cpp> | ||
+ | struct Goat { | ||
+ | template< | ||
+ | void eat(T); | ||
+ | }; | ||
+ | </ | ||
+ | |||
+ | Il n'est pas possible de laisser '' | ||
+ | |||
+ | [[https:// | ||
+ | |||
+ | ====Migration C++17 vers C++20==== | ||
+ | |||
+ | * Code C++17 | ||
+ | |||
+ | <code cpp> | ||
+ | #include < | ||
+ | |||
+ | template < | ||
+ | concept bool IShape = requires (T x, T z, int y) | ||
+ | { | ||
+ | { T() } ; | ||
+ | { x = z } -> T&; | ||
+ | { T(x) } ; | ||
+ | { x.countSides() } -> int; | ||
+ | { x.sideLength(y) } -> int; | ||
+ | }; | ||
+ | |||
+ | struct Rectangle | ||
+ | { | ||
+ | | ||
+ | | ||
+ | | ||
+ | |||
+ | const char * getName() { return " | ||
+ | int countSides() {return 4;} | ||
+ | int sideLength(int side) { return (side % 2 == 0) ? 10 : 5; } | ||
+ | }; | ||
+ | |||
+ | struct Square | ||
+ | { | ||
+ | | ||
+ | | ||
+ | | ||
+ | |||
+ | const char * getName() { return " | ||
+ | int countSides() {return 4;} | ||
+ | int sideLength(int side) { return 10; } | ||
+ | }; | ||
+ | |||
+ | void print(IShape& | ||
+ | { | ||
+ | for (int side = 0 ; side < shape.countSides() ; ++side ) | ||
+ | { | ||
+ | //std::cout << shape.getName() << " side=" << shape.sideLength(side) << " | ||
+ | } | ||
+ | }; | ||
+ | |||
+ | int main() | ||
+ | { | ||
+ | | ||
+ | | ||
+ | auto shapes = std:: | ||
+ | | ||
+ | |||
+ | | ||
+ | }; | ||
+ | </ | ||
+ | |||
+ | * Code C++20 | ||
+ | |||
+ | <code cpp> | ||
+ | #include < | ||
+ | #include < | ||
+ | |||
+ | template < | ||
+ | concept IShape = requires (T x, T z, int y) | ||
+ | { | ||
+ | { T() } ; | ||
+ | { x = z } -> std:: | ||
+ | { T(x) } ; | ||
+ | { x.countSides() } -> std:: | ||
+ | { x.sideLength(y) } -> std:: | ||
+ | }; | ||
+ | |||
+ | struct Rectangle | ||
+ | { | ||
+ | | ||
+ | | ||
+ | | ||
+ | |||
+ | const char * getName() { return " | ||
+ | int countSides() {return 4;} | ||
+ | int sideLength(int side) { return (side % 2 == 0) ? 10 : 5; } | ||
+ | }; | ||
+ | |||
+ | struct Square | ||
+ | { | ||
+ | | ||
+ | | ||
+ | | ||
+ | |||
+ | const char * getName() { return " | ||
+ | int countSides() {return 4;} | ||
+ | int sideLength(int side) { return 10; } | ||
+ | }; | ||
+ | |||
+ | void print(IShape auto& shape) | ||
+ | { | ||
+ | for (int side = 0 ; side < shape.countSides() ; ++side ) | ||
+ | { | ||
+ | //std::cout << shape.getName() << " side=" << shape.sideLength(side) << " | ||
+ | } | ||
+ | }; | ||
+ | |||
+ | int main() | ||
+ | { | ||
+ | | ||
+ | | ||
+ | auto shapes = std:: | ||
+ | | ||
+ | |||
+ | | ||
+ | }; | ||
</ | </ |
lang/cpp/concept.1580936283.txt.gz · Dernière modification : de root