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

Prochaine révision
Révision précédente
lang:cpp:templatespecialisation [2021/04/21 13:00] – Importation des codes de spécialisation des template rootlang:cpp:templatespecialisation [2021/07/05 09:51] (Version actuelle) – Déplacement de Divers en bas root
Ligne 1: Ligne 1:
 +====Spécialisation partielle====
 +
 +===Il faut commencer par spécialiser le premier template===
 +
 +  * Classe template
 +
 +<code cpp>
 +template<typename T>
 +class A
 +{
 +    template<typename U>
 +    class B
 +    {
 +    };
 +};
 +
 +// OK
 +template<>
 +template<typename U>
 +class A<int>::B
 +{
 +    int b;
 +};
 +
 +// KO
 +template<typename T>
 +template<>
 +class A<T>::B<int>
 +{
 +    int b;
 +};
 +
 +</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 262: 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.1619002822.txt.gz · Dernière modification : 2021/04/21 13:00 de root