Outils pour utilisateurs

Outils du site


lang:cpp:templatespecialisation

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:templatespecialisation [2021/04/21 13:19] – Ajout de "Empêcher l'utilisation du template non spécialisé" rootlang:cpp:templatespecialisation [2021/07/05 09:51] (Version actuelle) – Déplacement de Divers en bas root
Ligne 1: Ligne 1:
-====Divers====+====Spécialisation partielle====
  
-===Empêcher l'utilisation du template non spécialisé===+===Il faut commencer par spécialiser le premier template===
  
-''static_assert(false)'' ne peut être utilisé directement car il est systématiquement évalué par le compilateur. Il faut feinter...+  * Classe template
  
 <code cpp> <code cpp>
-#include <type_traits>+template<typename T> 
 +class A 
 +
 +    template<typename U> 
 +    class B 
 +    { 
 +    }; 
 +};
  
-template <typename T+// OK 
-struct foobar std::false_type {};+template<> 
 +template<typename U
 +class A<int>::
 +{ 
 +    int b; 
 +};
  
-// Template général. +// KO 
-template <class T> +template<typename T> 
-T fun(T a) { +template<> 
-  static_assert(foobar<T>::value, +class A<T>::B<int> 
-                "this function has to be implemented for desired type")+{ 
-}+    int b
 +};
  
-template <> 
-int fun(int a) { 
-  return a; 
-} 
- 
-int main() { 
-  // fun<char>('a'); // Echec 
-  fun<int>(10); 
-  // fun<float>(10.14); // Echec 
-} 
 </code> </code>
  
 +  * 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'activer certaines spécialisations de template en fonction du type.
 +
 +''std::enable_if'' permet d'activer sous condition une fonction template. Le premier argument est la condition, le deuxième argument est le type de retour de la fonction.
 +
 +<code cpp>
 +#include <type_traits>
 +
 +struct I {
 +  using R = int;
 +};
 +
 +struct F {
 +  using R = float;
 +};
 +
 +class A {
 + public:
 +  template <typename T>
 +  static typename std::enable_if_t<std::is_same_v<T, I>, I::R> f() {
 +    return 1;
 +  }
 +
 +  template <typename T>
 +  static typename std::enable_if_t<std::is_same_v<T, F>, F::R> f() {
 +    return 27;
 +  }
 +};
 +
 +int main() { return A::f<I>() + A::f<F>(); }
 +</code>
 ====Décorateur==== ====Décorateur====
  
Ligne 295: Ligne 330:
  
 [[https://stackoverflow.com/questions/6674795/how-to-call-generic-template-function-in-a-specialization-version|How to call generic template function in a specialization version]] {{ :lang:cpp:template:c_-_how_to_call_generic_template_function_in_a_specialization_version_-_stack_overflow_2020-02-06_23_35_03_.html |Archive du 13/07/2011 le 06/02/2020}} [[https://stackoverflow.com/questions/6674795/how-to-call-generic-template-function-in-a-specialization-version|How to call generic template function in a specialization version]] {{ :lang:cpp:template:c_-_how_to_call_generic_template_function_in_a_specialization_version_-_stack_overflow_2020-02-06_23_35_03_.html |Archive du 13/07/2011 le 06/02/2020}}
 +
 +====Divers====
 +
 +===Empêcher l'utilisation du template non spécialisé===
 +
 +''static_assert(false)'' ne peut être utilisé directement car il est systématiquement évalué par le compilateur. Il faut ajouter un niveau d'indirection.
 +
 +<code cpp>
 +#include <type_traits>
 +
 +template <typename T>
 +struct foobar : std::false_type {};
 +
 +// Template général.
 +template <class T>
 +T fun(T a) {
 +  // La variable value n'est évaluée que si la méthode est utilisée.
 +  static_assert(foobar<T>::value,
 +                "this function has to be implemented for desired type");
 +}
 +
 +template <>
 +int fun(int a) {
 +  return a;
 +}
 +
 +int main() {
 +  // fun<char>('a'); // Echec
 +  fun<int>(10);
 +  // fun<float>(10.14); // Echec
 +}
 +</code>
 +
 +Autre exemple avec ''std::conditional'':
 +
 +<code cpp>
 +#include <type_traits>
 +
 +struct A
 +{
 +  using Ty = int;
 +};
 +
 +struct B {};
 +
 +// KO, should be OK.
 +// using Ttrue = std::conditional_t<true, A::Ty, B::Ty>;
 +// KO
 +// using Tfalse = std::conditional_t<false, A::Ty, B::Ty>;
 +
 +template <typename T>
 +struct LazyLoadIdentity
 +{
 +  using type = T;
 +};
 +
 +template <typename T>
 +struct LazyLoadTy : LazyLoadIdentity<typename T::Ty> {};
 +
 +// OK
 +using Ttrue = std::conditional_t<true, LazyLoadTy<A>, LazyLoadTy<B>>::type;
 +// KO
 +//using Tfalse = std::conditional_t<false, LazyLoadTy<A>, LazyLoadTy<B>>::type;
 +</code>
 +
 +[[https://stackoverflow.com/questions/34281017/is-it-possible-to-build-a-lazy-conditional-metafunction|Is it possible to build a lazy conditional metafunction]] {{ :lang:cpp:template:c_-_is_it_possible_to_build_a_lazy_conditional_metafunction_-_stack_overflow_2021-05-17_22_08_45_.html |Archive du 15/12/2015 le 17/05/2021}}
  
lang/cpp/templatespecialisation.1619003975.txt.gz · Dernière modification : 2021/04/21 13:19 de root