IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Vous êtes nouveau sur Developpez.com ? Créez votre compte ou connectez-vous afin de pouvoir participer !

Vous devez avoir un compte Developpez.com et être connecté pour pouvoir participer aux discussions.

Vous n'avez pas encore de compte Developpez.com ? Créez-en un en quelques instants, c'est entièrement gratuit !

Si vous disposez déjà d'un compte et qu'il est bien activé, connectez-vous à l'aide du formulaire ci-dessous.

Identifiez-vous
Identifiant
Mot de passe
Mot de passe oublié ?
Créer un compte

L'inscription est gratuite et ne vous prendra que quelques instants !

Je m'inscris !

C++26 : Concept et templates variables comme paramètre template
Par Sandor Dargo

Le , par Sandor Dargo

6PARTAGES

12  0 
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
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
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
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
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
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
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
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
Vous avez lu gratuitement 5 453 articles depuis plus d'un an.
Soutenez le club developpez.com en souscrivant un abonnement pour que nous puissions continuer à vous proposer des publications.

Une erreur dans cette actualité ? Signalez-nous-la !