lang:cpp:template
Différences
Ci-dessous, les différences entre deux révisions de la page.
Les deux révisions précédentesRévision précédenteProchaine révision | Révision précédente | ||
lang:cpp:template [2021/05/13 18:12] – Ajout de "Erreurs" root | lang:cpp:template [2025/02/05 10:07] (Version actuelle) – [const Args...] : fix typo root | ||
---|---|---|---|
Ligne 1: | Ligne 1: | ||
+ | =====Restriction===== | ||
+ | |||
+ | ====Auto déduction==== | ||
+ | |||
+ | Il n'est pas possible de faire de l' | ||
+ | |||
+ | <code cpp> | ||
+ | typename< | ||
+ | R fonction() | ||
+ | { | ||
+ | return 1; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | Il faut utiliser '' | ||
+ | |||
+ | <code cpp> | ||
+ | auto fonction() | ||
+ | { | ||
+ | return 1; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ====const Args...==== | ||
+ | |||
+ | Il faut éviter les '' | ||
+ | |||
+ | Sinon, cela impose l' | ||
+ | |||
+ | <code cpp> | ||
+ | template< | ||
+ | void f(const Args&& | ||
+ | |||
+ | f(1.2); | ||
+ | </ | ||
+ | |||
+ | J'ai déjà eu des codes plus complexes où cela posait problème. | ||
+ | |||
=====Héritage===== | =====Héritage===== | ||
====CRTP (Curiously recurring template pattern)==== | ====CRTP (Curiously recurring template pattern)==== | ||
Ligne 268: | Ligne 306: | ||
====Séparer le code source des fonctions et leur définition dans une classe template==== | ====Séparer le code source des fonctions et leur définition dans une classe template==== | ||
+ | |||
+ | * Exemple avec une classe template | ||
+ | |||
C'est possible de ne pas être obligé de rendre '' | C'est possible de ne pas être obligé de rendre '' | ||
Ligne 287: | Ligne 328: | ||
void T< | void T< | ||
+ | // On instancie uniquement T< | ||
template class T< | template class T< | ||
</ | </ | ||
Ligne 296: | Ligne 338: | ||
<file cpp main.cc> | <file cpp main.cc> | ||
#include " | #include " | ||
- | |||
- | extern template class T< | ||
int main() | int main() | ||
{ | { | ||
T< | T< | ||
- | return tint.retval(); | + | return tint.fff(); |
} | } | ||
</ | </ | ||
+ | * Exemple avec une fonction template | ||
+ | |||
+ | <file cpp file.h> | ||
+ | class A { | ||
+ | template< | ||
+ | void f(); | ||
+ | }; | ||
+ | </ | ||
+ | |||
+ | <file cpp file.cpp> | ||
+ | template< | ||
+ | |||
+ | // Instanciation pour U=int | ||
+ | template void A:: | ||
+ | |||
+ | // Spécialisation pour U=double | ||
+ | template<> | ||
+ | </ | ||
+ | |||
+ | * Exemple avec une fonction template dans une classe template | ||
+ | |||
+ | <file cpp file.h> | ||
+ | template< | ||
+ | class A { | ||
+ | template< | ||
+ | void f(U u); | ||
+ | }; | ||
+ | </ | ||
+ | |||
+ | <file cpp file.cpp> | ||
+ | template< | ||
+ | |||
+ | template void A< | ||
+ | </ | ||
+ | |||
+ | * Messages d' | ||
+ | |||
+ | '' | ||
+ | |||
+ | '' | ||
+ | |||
+ | '' | ||
+ | |||
+ | Il ne faut pas utiliser une classe spécialisée avant qu' | ||
+ | |||
+ | <code cpp> | ||
+ | template < | ||
+ | class A {}; | ||
+ | |||
+ | // Doit être défini après la spécialisation. | ||
+ | A< | ||
+ | |||
+ | template <> | ||
+ | class A< | ||
+ | </ | ||
====Afficher en string le type template==== | ====Afficher en string le type template==== | ||
<code cpp> | <code cpp> | ||
Ligne 467: | Ligne 562: | ||
AA2< | AA2< | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ====Sérialisation==== | ||
+ | |||
+ | Compter le nombre de champ d'une classe. | ||
+ | |||
+ | <code cpp> | ||
+ | #include < | ||
+ | |||
+ | struct UniversalType { | ||
+ | template < | ||
+ | operator T(); // no definition required | ||
+ | }; | ||
+ | |||
+ | template < | ||
+ | consteval auto MemberCounter(auto... c0) { | ||
+ | if constexpr (requires { T{{A0{}}..., | ||
+ | return MemberCounter< | ||
+ | else if constexpr ( | ||
+ | requires { | ||
+ | T{{A0{}}..., | ||
+ | } || | ||
+ | requires { | ||
+ | T{{A0{}}..., | ||
+ | }) | ||
+ | return MemberCounter< | ||
+ | return sizeof...(A0) + sizeof...(c0); | ||
+ | } | ||
+ | |||
+ | int main() { | ||
+ | using TestType = struct { | ||
+ | int x[3]; | ||
+ | float y; | ||
+ | char z; | ||
+ | }; | ||
+ | auto [a, b, c] = TestType{}; | ||
+ | std::cout << MemberCounter< | ||
} | } | ||
</ | </ | ||
Ligne 472: | Ligne 605: | ||
====Erreurs==== | ====Erreurs==== | ||
- | * '' | + | * Il manque un mot clé '' |
+ | |||
+ | Il faut parfois rajouter le mot clé '' | ||
<code cpp> | <code cpp> | ||
Ligne 479: | Ligne 614: | ||
| | ||
</ | </ | ||
- | |||
- | Il manque un '' | ||
<code cpp> | <code cpp> | ||
return T::template f< | return T::template f< | ||
+ | </ | ||
+ | |||
+ | * Il manque un mot clé '' | ||
+ | |||
+ | <code cpp> | ||
+ | error: expected ';' | ||
+ | retval-> | ||
+ | ^ | ||
+ | ; | ||
+ | </ | ||
+ | |||
+ | ou encore | ||
+ | |||
+ | <code cpp> | ||
+ | error: expression contains unexpanded parameter pack ' | ||
+ | retval-> | ||
+ | ^ ~ | ||
+ | </ | ||
+ | |||
+ | ou encore | ||
+ | |||
+ | <code cpp> | ||
+ | error: expected primary-expression before ' | ||
+ | return this-> | ||
+ | ^ | ||
+ | </ | ||
+ | |||
+ | Solution: | ||
+ | |||
+ | <code cpp> | ||
+ | retval-> | ||
+ | </ | ||
+ | |||
+ | ===Mapping d'un type vers un autre via une map=== | ||
+ | |||
+ | https:// | ||
+ | |||
+ | < | ||
+ | using my_map = type_map< | ||
+ | pair< | ||
+ | pair< | ||
+ | pair< | ||
+ | >; | ||
+ | |||
+ | static_assert(std:: | ||
+ | static_assert(std:: | ||
+ | static_assert(std:: | ||
+ | </ | ||
+ | |||
+ | <code cpp> | ||
+ | template < | ||
+ | struct type_tag | ||
+ | { | ||
+ | using type = T; | ||
+ | }; | ||
+ | |||
+ | template < | ||
+ | struct pair | ||
+ | { | ||
+ | using first_type = K; | ||
+ | using second_type = V; | ||
+ | }; | ||
+ | |||
+ | template < | ||
+ | struct element | ||
+ | { | ||
+ | static auto value(type_tag< | ||
+ | -> type_tag< | ||
+ | }; | ||
+ | |||
+ | template < | ||
+ | struct type_map : element< | ||
+ | { | ||
+ | using element< | ||
+ | |||
+ | template < | ||
+ | using find = typename decltype(type_map:: | ||
+ | }; | ||
</ | </ |
lang/cpp/template.1620922337.txt.gz · Dernière modification : 2021/05/13 18:12 de root