Outils pour utilisateurs

Outils du site


lang:cpp:concept

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentesRévision précédente
Prochaine révision
Révision précédente
lang:cpp:concept [2020/02/10 13:09] – Meilleur exemple sur les fonctions rootlang:cpp:concept [2021/11/13 09:04] (Version actuelle) – Ajout de "Restriction" "Fonction template" root
Ligne 17: Ligne 17:
 template <typename T> template <typename T>
 // Le type est cv. Donc, il faut utiliser deux paramètres, l'un pour const, l'autre sans. // Le type est cv. Donc, il faut utiliser deux paramètres, l'un pour const, l'autre sans.
-concept Shape = requires(const T t, T u)+concept Shape = requires(const T t, T u, float f)
 { {
-  // Le type de retour est faculatif mais conseillé. +  // Le type de retour est facultatif mais conseillé. 
-  { t.area() } -> float; +  { t.area() } -> std::same_as<float>
-  { u.mod() } -> float; +  { u.mod(f) } -> std::same_as<float>
-  // On impose une variable. Elle peut être static / constexpr ou non. +  // On impose une variable. 
-  { t.varr } -> float;+  // Elle peut être static / constexpr ou non
 +  // Il faut la déclarer comme une référence
 +  { t.varr } -> std::same_as<const float&>;
 }; };
 </code> </code>
Ligne 33: Ligne 35:
 { {
     consteval float area() const {return 1.;}     consteval float area() const {return 1.;}
-    consteval float mod() {return 1.;}+    consteval float mod(float f) {return f;}
     static constexpr float varr = 2.f;     static constexpr float varr = 2.f;
 }; };
Ligne 59: Ligne 61:
   b.mod();   b.mod();
 } }
 +</code>
 +
 +  * 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<class T>
 +    void eat(T);
 +};
 +</code>
 +
 +Il n'est pas possible de laisser ''eat'' template. Il faudra définir explicitement chaque surcharge.
 +
 +[[https://quuxplusone.github.io/blog/2020/08/10/concepts-cant-do-quantifiers/|Concepts can’t do quantifiers]] {{ :lang:cpp:concept:concepts_can_t_do_quantifiers_arthur_o_dwyer_stuff_mostly_about_c_2021-11-13_09_03_00_.html |Archive du 10/08/2020 le 13/11/2021}}
 +
 +====Migration C++17 vers C++20====
 +
 +  * Code C++17
 +
 +<code cpp>
 +#include <tuple>
 +
 +template <typename T>
 +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
 +{
 +   Rectangle() {};
 +   Rectangle(const Rectangle& other) {};
 +   Rectangle& operator=(Rectangle& other) {return *this; };
 +
 +   const char * getName() { return "Rectangle"; }
 +   int countSides() {return 4;}
 +   int sideLength(int side) { return (side % 2 == 0) ? 10 : 5; }
 +};
 +
 +struct Square
 +{
 +   Square() {};
 +   Square(const Square& other) {};
 +   Square& operator=(Square& other) {return *this; };  
 +
 +   const char * getName() { return "Square"; }
 +   int countSides() {return 4;}
 +   int sideLength(int side) { return 10; }
 +};
 +
 +void print(IShape& shape)
 +{
 +   for (int side = 0 ; side < shape.countSides() ; ++side )
 +   {
 +      //std::cout << shape.getName() << " side=" << shape.sideLength(side) << "\n";
 +   }
 +};
 +
 +int main()
 +{
 +   Square square;
 +   Rectangle rect;
 +   auto shapes = std::make_tuple(square, rect);
 +   std::apply([](auto&... shape) { ((print(shape)), ...); }, shapes) ;
 +
 +   return 0;
 +};
 +</code>
 +
 +  * Code C++20
 +
 +<code cpp>
 +#include <concepts>
 +#include <tuple>
 +
 +template <typename T>
 +concept IShape = requires (T x, T z, int y)
 +{
 +   { T() } ;
 +   { x = z } -> std::same_as<T&>;
 +   { T(x) }  ;
 +   { x.countSides() } -> std::same_as<int>;
 +   { x.sideLength(y) } -> std::same_as<int>;
 +};
 +
 +struct Rectangle
 +{
 +   Rectangle() {};
 +   Rectangle(const Rectangle& other) {};
 +   Rectangle& operator=(Rectangle& other) {return *this; };
 +
 +   const char * getName() { return "Rectangle"; }
 +   int countSides() {return 4;}
 +   int sideLength(int side) { return (side % 2 == 0) ? 10 : 5; }
 +};
 +
 +struct Square
 +{
 +   Square() {};
 +   Square(const Square& other) {};
 +   Square& operator=(Square& other) {return *this; };  
 +
 +   const char * getName() { return "Square"; }
 +   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) << "\n";
 +   }
 +};
 +
 +int main()
 +{
 +   Square square;
 +   Rectangle rect;
 +   auto shapes = std::make_tuple(square, rect);
 +   std::apply([](auto&... shape) { ((print(shape)), ...); }, shapes) ;
 +
 +   return 0;
 +};
 </code> </code>
lang/cpp/concept.1581336555.txt.gz · Dernière modification : 2020/02/10 13:09 de root