lang:cpp:templatespecialisation
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:templatespecialisation [2021/05/17 22:11] – [Empêcher l'utilisation du template non spécialisé] root | lang:cpp:templatespecialisation [2025/11/14 12:02] (Version actuelle) – Réécriture complète root | ||
|---|---|---|---|
| Ligne 1: | Ligne 1: | ||
| - | ====Divers==== | + | =====Spécialisation complète===== |
| - | ===Empêcher l' | + | ====Appeler la méthode généralisée depuis la méthode spécialisée==== |
| + | |||
| + | C'est impossible. La solution est que la méthode de base s' | ||
| + | |||
| + | <code cpp> | ||
| + | template< | ||
| + | void baseF(T t) { ... } | ||
| + | |||
| + | template< | ||
| + | void F(T t) { baseF< | ||
| + | |||
| + | template<> | ||
| + | void F< | ||
| + | </ | ||
| + | |||
| + | [[https:// | ||
| + | |||
| + | ====Empêcher l' | ||
| '' | '' | ||
| Ligne 64: | Ligne 81: | ||
| [[https:// | [[https:// | ||
| - | ====Spécialisation partielle==== | ||
| - | ===Il faut commencer par spécialiser le premier template=== | + | ====Exemples==== |
| - | * Classe template | + | ===Décorateur |
| - | + | ||
| - | <code cpp> | + | |
| - | template< | + | |
| - | class A | + | |
| - | { | + | |
| - | template< | + | |
| - | class B | + | |
| - | { | + | |
| - | }; | + | |
| - | }; | + | |
| - | + | ||
| - | // OK | + | |
| - | template<> | + | |
| - | template< | + | |
| - | class A< | + | |
| - | { | + | |
| - | int b; | + | |
| - | }; | + | |
| - | + | ||
| - | // KO | + | |
| - | template< | + | |
| - | template<> | + | |
| - | class A< | + | |
| - | { | + | |
| - | int b; | + | |
| - | }; | + | |
| - | + | ||
| - | </ | + | |
| - | + | ||
| - | * Fonction template | + | |
| - | + | ||
| - | Il n'est pas possible de faire de la spécialisation partielle de template comme pour les classes. | + | |
| - | + | ||
| - | Mais il est possible d' | + | |
| - | + | ||
| - | '' | + | |
| - | + | ||
| - | <code cpp> | + | |
| - | #include < | + | |
| - | + | ||
| - | struct I { | + | |
| - | using R = int; | + | |
| - | }; | + | |
| - | + | ||
| - | struct F { | + | |
| - | using R = float; | + | |
| - | }; | + | |
| - | + | ||
| - | class A { | + | |
| - | | + | |
| - | template < | + | |
| - | static typename std:: | + | |
| - | return 1; | + | |
| - | } | + | |
| - | + | ||
| - | template < | + | |
| - | static typename std:: | + | |
| - | return 27; | + | |
| - | } | + | |
| - | }; | + | |
| - | + | ||
| - | int main() { return A:: | + | |
| - | </ | + | |
| - | ====Décorateur==== | + | |
| [[https:// | [[https:// | ||
| - | * implicit return type | ||
| <code cpp> | <code cpp> | ||
| #include < | #include < | ||
| Ligne 187: | Ligne 138: | ||
| </ | </ | ||
| - | * explicit return type | + | <file cpp main.cc> |
| - | + | ||
| - | <code cpp> | + | |
| - | #include < | + | |
| - | #include < | + | |
| - | + | ||
| - | struct Action1 { using Type = void; }; | + | |
| - | struct Action2 { using Type = char; }; | + | |
| - | + | ||
| - | class Classe | + | |
| - | { | + | |
| - | public: | + | |
| - | // Default template. | + | |
| - | template< | + | |
| - | T go(Args ...args) | + | |
| - | { | + | |
| - | // | + | |
| - | } | + | |
| - | }; | + | |
| - | + | ||
| - | // Action 1. | + | |
| - | template<> | + | |
| - | Action1:: | + | |
| - | { | + | |
| - | std::cout << " | + | |
| - | } | + | |
| - | + | ||
| - | // Action 2. | + | |
| - | template<> | + | |
| - | Action2:: | + | |
| - | { | + | |
| - | std::cout << " | + | |
| - | return i; | + | |
| - | } | + | |
| - | + | ||
| - | template <class T> | + | |
| - | class Decorator | + | |
| - | { | + | |
| - | public: | + | |
| - | Decorator(std:: | + | |
| - | + | ||
| - | template< | + | |
| - | auto go(Args ...args) | + | |
| - | { | + | |
| - | std::cout << " | + | |
| - | return classe-> | + | |
| - | } | + | |
| - | private: | + | |
| - | std:: | + | |
| - | }; | + | |
| - | </ | + | |
| - | + | ||
| - | * main.cc | + | |
| - | + | ||
| - | <code cpp> | + | |
| int main() | int main() | ||
| { | { | ||
| Ligne 248: | Ligne 145: | ||
| c.go< | c.go< | ||
| } | } | ||
| - | </code> | + | </file> |
| - | + | ||
| - | ====metaprogrammation vs constexpr==== | + | |
| - | ===Exemple simple=== | + | |
| - | <code cpp> | + | |
| - | #include < | + | |
| - | + | ||
| - | template < | + | |
| - | constexpr T square(T x) { | + | |
| - | return x*x; | + | |
| - | } | + | |
| - | + | ||
| - | int main() { | + | |
| - | printf(" | + | |
| - | // 11.560000 9 | + | |
| - | } | + | |
| - | </code> | + | |
| - | ===Fibonacci=== | + | ===Fibonacci |
| * Template | * Template | ||
| Ligne 316: | Ligne 197: | ||
| <WRAP center round important 60%> | <WRAP center round important 60%> | ||
| - | Le code est beaucoup moins optimisé | + | Le code est beaucoup moins optimisé avec constexpr. Il aurait fallu d' |
| </ | </ | ||
| - | ===Nombres premiers=== | + | ===Nombres premiers |
| * Template | * Template | ||
| Ligne 380: | Ligne 261: | ||
| gcc et clang arrive à calculer à la compilation. | gcc et clang arrive à calculer à la compilation. | ||
| - | ====Appeler la méthode généralisée depuis la méthode spécialisée==== | + | =====Spécialisation partielle===== |
| - | C'est impossible. | + | |
| + | ====Template imbriqué==== | ||
| + | |||
| + | Il faut spécialiser le template parent avant de pouvoir spécialiser le template enfant. | ||
| + | |||
| + | * Classe template | ||
| <code cpp> | <code cpp> | ||
| template< | template< | ||
| - | void baseF(T t) { ... } | + | class A |
| + | { | ||
| + | template< | ||
| + | class B | ||
| + | { | ||
| + | }; | ||
| + | }; | ||
| - | template< | + | // OK |
| - | void F(T t) { baseF<T>(t); } | + | template<> |
| + | template< | ||
| + | class A<int>::B | ||
| + | { | ||
| + | int b; | ||
| + | }; | ||
| + | // KO | ||
| + | template< | ||
| template<> | template<> | ||
| - | void F<int>(int t) { baseF<int>(t); } | + | class A<T>::B<int> |
| + | { | ||
| + | int b; | ||
| + | }; | ||
| </ | </ | ||
| - | [[https:// | + | ====Fonction |
| + | Il n'est pas possible de faire de la spécialisation partielle de template comme pour les classes. | ||
| + | |||
| + | * '' | ||
| + | |||
| + | Il est possible d' | ||
| + | |||
| + | '' | ||
| + | |||
| + | <code cpp> | ||
| + | #include < | ||
| + | |||
| + | struct I { | ||
| + | using R = int; | ||
| + | }; | ||
| + | |||
| + | struct F { | ||
| + | using R = float; | ||
| + | }; | ||
| + | |||
| + | class A { | ||
| + | | ||
| + | template < | ||
| + | static typename std:: | ||
| + | return 1; | ||
| + | } | ||
| + | |||
| + | template < | ||
| + | static typename std:: | ||
| + | return 27; | ||
| + | } | ||
| + | }; | ||
| + | |||
| + | int main() { return A:: | ||
| + | </ | ||
| + | |||
| + | * Utilisation d'une classe | ||
| + | |||
| + | Si la méthode est static, le plus simple est de passer par des classes qui ne contionnent qu'une seule méthode, celle à spécialiser partiellement. | ||
| + | |||
| + | <code cpp> | ||
| + | template < | ||
| + | struct A { | ||
| + | static int foo(U) { return 1; } | ||
| + | }; | ||
| + | |||
| + | template < | ||
| + | struct A<T, int> { | ||
| + | static int foo(int) { return 2; } | ||
| + | }; | ||
| + | </ | ||
lang/cpp/templatespecialisation.1621282305.txt.gz · Dernière modification : de root
