août
2008
Aujourd’hui je vais tenter de vous intéresser à une possibilité du C++ qui ne prendra effet qu’après la publication de la prochaine norme (C++0x, qui devrait si tout va bien devenir C++09), le temps que les compilateurs l’implémentent, qui est résumée sous le doux nom de variadic templates.
Est-ce que vous vous souvenez de la fonction printf de la bibliothèque standard C ?
Au cas où, je vous rappelle son prototype :
int printf (const char *format, ...);
Vous vous souvenez aussi probablement que les « … » permettent de donner autant d’arguments que l’on souhaite à printf et que l’on appelle cela les ellipses. Les fonctions qui utilisent ceci sont appelées fonctions variadiques.
Avec le C++ actuel, nous pouvons toujours utiliser cette technique.
Seulement, une grande nouveauté va être apportée au C++. Elle reprend l’idée des fonctions variadiques mais pour l’appliquer… aux paramètres d’une fonction ou classe template !
En effet, nous allons en C++0x pouvoir créer des classes et fonctions templates pouvant accepter un nombre arbitraire d’arguments (pour les fonctions) et de paramètres (pour les classes/structures), non fixé à l’avance.
Pour mieux vous présenter comment cela sera fait, je vais d’abord donner quelques définitions.
- template parameter pack : c’est un paramètre template qui accepte zéro ou plus arguments templates. On donne généralement l’exemple suivant.
template<class ... Types> struct Tuple { };
Ici class … Types est donc un template parameter pack. Sachez aussi que c’est cette syntaxe qui sera utilisée en C++0x. - function parameter pack : c’est un paramètre de fonction qui accepte zéro ou plus arguments de fonctions. Un exemple illustrant mes propos ci-dessous.
template<class ... Types> void f(Types ... args);
Ici Types … args est un function parameter pack. Ici aussi on est en présence de la syntaxe définitive adoptée pour C++0x. - On dénote par parameter pack soit un template parameter pack soit un function parameter pack.
- pack expansion : c’est une expression qui permet de donner à une fonction, une liste d’initialisation, etc un ou plusieurs parameter packs. Voici un exemple.
template<class ... Types> void f(Types ... rest);
template<class ... Types> void g(Types ... rest) {
f(&rest ...);
}Ici &rest … est une pack expansion.
Et maintenant, il ne reste plus qu’à présenter la règle qui définit l’utilisation des expansions :
Un parameter pack dont le nom apparaît dans une pack expansion est « étendu » par cette pack expansion. Toutefois, l’expansion ne se fait que par la pack expansion la plus intérieure (par rapport aux parenthèses et chevrons ( < et > ) qui ne doit toutefois pas être plus intérieure que le parameter pack.
Illustration en code.
template<class ... Args> void g(Args ... args) {
f(const_cast<const Args*>(&args)...); // Args et args sont étendus
f(5 ...); // erreur car l'expression ne contient aucun parameter pack
f(args); // erreur car le parameter pack 'args' n'est pas étendu
f(h(args ...) + args ...); // le premier 'args ...' est étendu dans h et le second dans f
}
Tout cela permettra d’écrire un code encore plus générique, notamment pour représenter des n-uplets (au sens mathématique) que l’on dénote généralement par tuples en programmation, ainsi que des classes utilitaires autour des fonctions et foncteurs comme Boost.Bind, Boost.Function, etc. Cette nouvelle possibilité fera donc des heureux dans l’univers de la programmation générique en C++ car elle apporte un plus à un programme de nouveautés autour des templates déjà bien chargé.
Je vous conseille de consulter le site du commité ISO de normalisation du C++ pour obtenir plus de détails sur toutes ces choses.
Ce billet a été écrit en se basant sur la version du 26 Juin 2008 du brouillon de la norme de C++0x et utilise les exemples donnés dans le document en question.
Très bon billet. ^^
Oui… Et nous sommes de tout coeur avec eux.
Mais de toute manière, que ce soit 9 ou a, à mon avis il va nous falloir un petit moment avant d’avoir un support correct de la norme 0x sur les compilateurs C++.
Exact, Bjarne Stroustrup lui-même lors d’une conférence a expliqué que le comité de standardisation travaillait très dur afin d’arriver à ce que le x ne se transforme pas en a ou b …
Héhé, bon billet.
Espérons que x soit évalué à 9