Outils pour utilisateurs

Outils du site


lang:cpp:template

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:template [2023/02/19 19:13] – Précisiont sur l'obligation de mettre le mot clé typename quand le symbole est suivi d'une explicitation du type rootlang:cpp:template [2025/02/05 10:07] (Version actuelle) – [const Args...] : fix typo root
Ligne 29: Ligne 29:
  
 <code cpp> <code cpp>
-typename<template ...Args>+template<typename ...Args>
 void f(const Args&&... args){} void f(const Args&&... args){}
  
Ligne 328: Ligne 328:
 void T<X>::fff() {} void T<X>::fff() {}
  
 +// On instancie uniquement T<int> (et donc T<int>::fff()).
 template class T<int>; template class T<int>;
 </file> </file>
Ligne 337: Ligne 338:
 <file cpp main.cc> <file cpp main.cc>
 #include "template.h" #include "template.h"
- 
-extern template class T<int>(); 
  
 int main() int main()
 { {
   T<int> tint;   T<int> tint;
-  return tint.retval();+  return tint.fff();
 } }
 </file> </file>
Ligne 357: Ligne 356:
  
 <file cpp file.cpp> <file cpp file.cpp>
-template<typename U> void A::f<U>(){}+template<typename U> void A::f(){} 
 + 
 +// Instanciation pour U=int 
 +template void A::f<int>();
  
-template void A::f<int>;+// Spécialisation pour U=double 
 +template<> void A::f<double>(){}
 </file> </file>
  
Ligne 377: Ligne 380:
 template void A<int>::f(short u); template void A<int>::f(short u);
 </file> </file>
 +
 +  * Messages d'erreur
 +
 +''error: specialization of XXX after instantiation''
 +
 +''error: explicit specialization of XXX after instantiation''
 +
 +''error C2908: explicit specialization; XXX has already been instantiated''
 +
 +Il ne faut pas utiliser une classe spécialisée avant qu'elle ne soit définie.
 +
 +<code cpp>
 +template <typename T>
 +class A {};
 +
 +// Doit être défini après la spécialisation.
 +A<int> a;
 +
 +template <>
 +class A<int> {};
 +</code>
 ====Afficher en string le type template==== ====Afficher en string le type template====
 <code cpp> <code cpp>
Ligne 538: Ligne 562:
  
   AA2<Types>::ff();   AA2<Types>::ff();
 +}
 +</code>
 +
 +====Sérialisation====
 +
 +Compter le nombre de champ d'une classe.
 +
 +<code cpp>
 +#include <iostream>
 +
 +struct UniversalType {
 +    template <typename T>
 +    operator T();  // no definition required
 +};
 +
 +template <typename T, typename... A0>
 +consteval auto MemberCounter(auto... c0) {
 +    if constexpr (requires { T{{A0{}}..., {UniversalType{}}, c0...}; })
 +        return MemberCounter<T, A0..., UniversalType>(c0...);
 +    else if constexpr (
 +        requires {
 +            T{{A0{}}..., {UniversalType{}}, c0...};
 +        } ||
 +        requires {
 +            T{{A0{}}..., c0..., UniversalType{}};
 +        })
 +        return MemberCounter<T, A0...>(c0..., UniversalType{});
 +    return sizeof...(A0) + sizeof...(c0);
 +}
 +
 +int main() {
 +    using TestType = struct {
 +        int x[3];
 +        float y;
 +        char z;
 +    };
 +    auto [a, b, c] = TestType{};                          // decomposes into 3
 +    std::cout << MemberCounter<TestType>() << std::endl;  // prints 3
 } }
 </code> </code>
Ligne 588: Ligne 650:
 </code> </code>
  
 +===Mapping d'un type vers un autre via une map===
 +
 +https://stackoverflow.com/questions/68668956/c-how-to-implement-a-compile-time-mapping-from-types-to-types
 +
 +<code>
 +using my_map = type_map<
 +    pair<int, float>,
 +    pair<char, double>,
 +    pair<long, short>
 +>;
 +
 +static_assert(std::is_same_v<my_map::find<int>, float>);
 +static_assert(std::is_same_v<my_map::find<char>, double>);
 +static_assert(std::is_same_v<my_map::find<long>, short>);
 +</code>
 +
 +<code cpp>
 +template <typename T>
 +struct type_tag
 +{
 +  using type = T;
 +};
 +
 +template <typename K, typename V>
 +struct pair
 +{
 +  using first_type = K;
 +  using second_type = V;
 +};
 +
 +template <typename Pair>
 +struct element
 +{
 +  static auto value(type_tag<typename Pair::first_type>)
 +      -> type_tag<typename Pair::second_type>;
 +};
 +
 +template <typename... elems>
 +struct type_map : element<elems>...
 +{
 +  using element<elems>::value...;
 +
 +  template <typename K>
 +  using find = typename decltype(type_map::value(type_tag<K>{}))::type;
 +};
 +</code>
lang/cpp/template.1676830423.txt.gz · Dernière modification : 2023/02/19 19:13 de root