C++26 : Concept et templates variables comme param�tre template, par Sandor Dargo
La semaine derni�re, nous avons discut� des raisons pour lesquelles il est parfois n�cessaire d'utiliser remove_cvref_t sur nos param�tres template avant de leur appliquer des concepts. Nous avons �galement vu que cette solution n'est pas tr�s lisible, car elle nous prive de la syntaxe concise et abr�g�e.
Si seulement nous pouvions utiliser les concepts comme param�tres template !
Heureusement, P2841R7 vient � notre secours, et il a r�cemment �t� accept� dans le cadre de C++26.
� premi�re vue, la proposition peut sembler intimidante, car elle compte pr�s de 40 pages. Mais ne vous inqui�tez pas. Tout d'abord, il s'agit d'un document tr�s lisible, rempli d'explications claires et d�taill�es. Ensuite, environ la moiti� consiste en des modifications de formulation.
Plongeons-nous dans le vif du sujet.
Les concepts en tant que template de param�tres template
Le C++ permet d�j� de passer des templates en tant que param�tres template, mais uniquement s'il s'agit de template de classe. Une raison courante pour cela est de permettre des abstractions de plus haut niveau. Par exemple, vous pouvez vouloir passer un template de conteneur comme std::vector, sans sp�cifier le type qu'il contient.
Jason Turner explique bien cela dans C++ Weekly - Ep 368 - The Power of template-template Parameters: A Basic Guide.
Mais voici son exemple pour r�f�rence rapide :
Code CPP : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4
5
6
7
8
9
10
11 template<template <typename Contained, typename Alloc = std::allocator<Contained>> typename ResultType> auto get_data() { ResultType<double> result; // ... return result; } int main() { auto data = get_data<std::vector>(); }
Avec une signature plus simple comme template<typename ResultType> auto get_data(), nous ne pouvions pas passer std::vector, car ce n'est pas un type complet, mais un template. Gr�ce aux templates de param�tres template, nous pouvons passer un template de classe � un autre template.
Malheureusement, jusqu'� pr�sent, cette technique ne fonctionnait pas avec les templates variables ou les concepts. Pourtant, la motivation pour passer un concept comme argument de template est similaire � celle qui nous pousse � passer des templates de classe : permettre des constructions expressives de haut niveau.
La semaine derni�re, nous avions ce template de fonction :
Code CPP : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3 template<typename Q> requires Quantity<std::remove_cvref_t<Q>> void foo(Q&& q);
Avec un template de concept des param�tres template, nous pouvons introduire un concept d'aide, en d'autres termes un adaptateur de concept, afin d'am�liorer la lisibilit� :
Code CPP : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3 template <typename T, <template <typename> concept C> concept decays_to = C<std::decay_t<T>>;
Cela nous permet de r��crire notre fonction de mani�re plus claire :
Code CPP : S�lectionner tout - Visualiser dans une fen�tre � part
1
2 template <decays_to<Quantity> Q> void foo(Q&& q);
La proposition comprend plusieurs autres exemples qui pourraient s'av�rer utiles.
Template variables - param�tre template
� partir de C++23, nous ne pouvons pas avoir de template variables param�tre template. Bien qu'il existe des solutions de contournement, telles que l'encapsulation de variables dans des structures avec un membre de valeur pour les utiliser comme type de Template variables - param�tre template de param�tres template, celles-ci sont verbeuses, difficiles � lire et peuvent avoir un impact n�gatif sur les performances.
En fait, la plupart des traits de type standard sont d�finis � la fois comme des types et des variables _v. Selon les benchmarks de performance de la proposition, l'utilisation de templates variables peut pr�senter des avantages significatifs en termes de performance de compilation et d'utilisation de la m�moire.
La diff�rence dans l'exemple de code pr�sent� dans le document est minime :
Code CPP : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4
5
6 // Before template <template <typename> typename p, typename... Ts> constexpr std::size_t count_if_v = (... + p<Ts>::value); // After template <template <typename> auto p, typename... Ts> constexpr std::size_t count_if_v = (... + p<Ts>);
En �liminant ::value, nous �vitons la surcharge li�e � l'instanciation d'un template de classe pour chaque Ts � un changement apparemment mineur, mais qui a un impact significatif.
Les d�tails syntaxiques
La raison pour laquelle le concept et les templates variables de param�tres template apparaissent ensemble dans cette proposition n'est pas fortuite. Bien qu'ils aient �t� propos�s s�par�ment auparavant, ils sont tous deux essentiels pour prendre en charge les param�tres template universels, propos�s dans P1985R3.
La proposition dont il est question ici (P2841R7) est en fait un sous-ensemble de P1985R3. Pour qu'un � param�tre template universel � soit � la hauteur de son nom, il doit prendre en charge un large �ventail de formes d'arguments de template possibles, notamment les types, les templates de classe, les concepts et les templates variables.
Voici comment nous sp�cifions habituellement un param�tre de mod�le de mod�le de classe uniquement :
Code CPP : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3 template< template <typename T> typename TT >
Avec la nouvelle proposition, nous pouvons d�sormais inclure des concepts et des templates variables en utilisant respectivement les mots-cl�s concept et auto :
Code CPP : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4
5 template< template <typename T> typename TT, template <typename T> concept C, template <typename T> auto VT >
Il existe de nombreux autres aspects int�ressants, comme la subsomption, mais je les aborderai dans un autre article afin que celui-ci reste concis et facile � comprendre.
Conclusion
L'acceptation de P2841R7 dans C++26 est l'une de ces am�liorations discr�tes mais puissantes. Elle nous permet d'�crire des mod�les plus propres, plus flexibles et plus faciles � lire en autorisant � la fois les concepts et les templates variables comme param�tres template.
Cela peut sembler �tre une fonctionnalit� de niche, mais si vous avez d�j� �t� confront� � une syntaxe de template maladroite ou � des wrappers standardis�s juste pour faire passer des concepts ou des traits, vous appr�cierez ce que cela vous apporte. Cela nous rapproche un peu plus de l'�criture d'un C++ expressif et de haut niveau qui semble plus naturel, sans sacrifier les performances.
C'est un grand pas en avant pour tous ceux qui appr�cient le C++ moderne et souhaitent disposer d'outils plus �l�gants pour la m�taprogrammation. Et soyons honn�tes, moins de ::value clutter n'a jamais fait de mal � personne.
Cet article est publi� sous licence CC BY 4.0 par l'auteur.
Source : "C++26: Concept and variable-template template-parameters"
Et vous ?
Quel est votre avis sur le sujet ?
Voir aussi :
La norme C++23 supprime la prise en charge du Garbage Collection, par Sandor Dargo, d�veloppeur C++
Le C++ doit �tre du C++ : Une opinion qui est le fruit de 23 ann�es d'exp�rience en C++, par David Sankel
C++ sous st�ro�des : Bjarne Stroustrup pr�sente des � profils � renforc�s par des lignes directrices pour la s�curit� des ressources et des types, afin de garantir que le code est contemporain et s�r




Quel est votre avis sur le sujet ?
R�pondre avec citation
Partager