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 paramètres de modèle variables
Par Sandor Dargo

Le , par Sandor Dargo

0PARTAGES

6  0 
C++26 : Concept et paramètres de modèle variables, 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 de modèle 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 de modèle !

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 paramètres de modèle de modèle

Le C++ permet déjà de passer des modèles en tant que paramètres de modèle, mais uniquement s'il s'agit de modèles de classe. Une raison courante pour cela est de permettre des abstractions de plus haut niveau. Par exemple, vous pouvez vouloir passer un modèle 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 modèle. Grâce aux paramètres template-template, nous pouvons passer un modèle de classe à un autre modèle.

Malheureusement, jusqu'à présent, cette technique ne fonctionnait pas avec les modèles variables ou les concepts. Pourtant, la motivation pour passer un concept comme argument de modèle est similaire à celle qui nous pousse à passer des modèles de classe : permettre des constructions expressives de haut niveau.

La semaine dernière, nous avions ce modèle 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 les paramètres de concept modèle-modèle, 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.

Paramètres de modèles variables

À partir de C++23, nous ne pouvons pas avoir de paramètres de modèles variables. 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 paramètres de modèles de types, 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 modèles 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 modèle 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 paramètres de modèle-modèle variables 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 de modèle 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 de modèle universel » soit à la hauteur de son nom, il doit prendre en charge un large éventail de formes d'arguments de modèle possibles, notamment les types, les modèles de classe, les concepts et les modèles 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 modèles de 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 modèles de variables comme paramètres de modèle.

Cela peut sembler être une fonctionnalité de niche, mais si vous avez déjà été confronté à une syntaxe de modèle 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 325 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 !

Avatar de dragonjoker59
Expert éminent sénior https://www.developpez.com
Le 24/09/2025 à 8:36
Article intéressant, mais il faut arrêter de tout traduire en français... En C++ un template est un template, pas un modèle... Et un variadic template est un variadic template, pas un modèle variable...
Un développeur ne rencontrera nulle part ailleurs qu'ici le terme "modèle variable". D'ailleurs la traduction automatique par Microsoft est "variadique" : https://learn.microsoft.com/fr-fr/cp...?view=msvc-170
2  0