Xavier Lamorlette

C++ : Templates

Sommaire :

Généralités

Les templates permettent de faire du polymorphisme à la compilation.

Spécialisation de template

template<typename T>
class Template {
   void foo(T param) {
   }
};

template<>
class Template<int> {
   void foo(int param) {
   }
};

Instanciation explicite

L'instanciation explicite d'un template permet d'éviter de mettre sa définition dans le fichier d'en-tête :

# A.hpp
template<typename T>
class A {
    A(T t);
};


# A.cpp
#include "A.hpp"

template<typename T>
A<T>::A(T t) {
    …
}

template class A<someType>;

Templates externes

Définir un template externe permet d'éviter l'instanciation implicite dans chaque unité de compilation :

template<typename T> class A {…};
extern template class A<someType>;

Il faut bien entendu une instanciation explicite dans une unité de compilation :

template class A<someType>;

Déduction du paramètre template par le constructeur (C++ 17)

Les types des paramètres d'une classe template peuvent être déduits à partir des arguments de son constructeur :

template <typename T>
class Foo {
public:
  Foo(const T & t) {
    std::cout << t << std::endl;
  }
};

Foo(1);
Foo(1.);

Ça permet de faire directement :

std::array int_array{1, 2};
std::vector double_vector{1.1, 1.2};
std::pair int_double_pair{1, 1.1};
std::tuple complex_tuple{1, int_double_pair};

Template Adapter

Classe template utilisée comme paramètre template.

Exemple :

template<typename T,
    template<typename> class Container_type = std::list>
class Stack {
public:
    void push(const T & element) {
        container.push_front(element);
    }

private:
    Container_type<T> container;
};

Variadic Templates

Ce qui est devant l'opérateur points de suspension ... (ellipsis operator) est répété, avec une virgule entre chaque répétition :

... répéte toute l'expression comprenant un parameter pack. Exemple : foo(bar(args)...).

Exemples :

template<typename T>
T Sum(T value) {
    return value;
}

template<typename T,
    typename... Args>
T Sum(T first,
        Args... args) {
    return first + Sum(args...);
}
template<typename T>
T Sum(const T & value) {
    return value;
}

template<typename T,
    typename... Args>
T Sum(const T & first,
        const Args & ... args) {
    return first + Sum(args ...);
}
template<typename... Args>
class Variadic_template {
    static const uint8_t size = sizeof...(Args);
};

Fold Expressions (C++ 17)

Une fold expression est une instruction pour demander au compilateur de répéter un opérateur binaire sur un parameter pack.

Exemples :

template<typename... Args>
bool All(Args... args) {
  return (... && args);
}

std::cout << std::boolalpha << All(true, false) << std::endl;
template<typename T,
    typename... Args>
T Sum(const Args & ... args) {
    return (args + ...);
}

Sum(1, 1u, 1.);

La dernière mise à jour de cette page date de septembre 2021.

Le contenu de ce site est, en tant qu'œuvre originale de l'esprit, protégé par le droit d'auteur.
Pour tout commentaire, vous pouvez m'écrire à xavier.lamorlette@gmail.com.