Un modèle de variable définit une famille de variables ou de membres de données statiques.
Syntaxe
|
|
template
<
parameter-list
>
variable-declaration
|
(1)
|
|
|
|
template
<
parameter-list
>
requires
constraint
variable-declaration
|
(2)
|
(since C++20)
|
|
|
Explication
Une variable instanciée à partir d'un modèle de variable est appelée une
variable instanciée
. Un membre de données statique instancié à partir d'un modèle de membre de données statique est appelé un
membre de données statique instancié
.
Une variable template peut être introduite par une déclaration template au niveau de l'espace de noms, où
variable-declaration
déclare une variable.
template<class T>
constexpr T pi = T(3.1415926535897932385L); // modèle de variable
template<class T>
T circular_area(T r) // modèle de fonction
{
return pi<T> * r * r; // pi<T> est une instanciation de modèle de variable
}
Lorsqu'il est utilisé au niveau de la classe, un modèle de variable déclare un modèle de membre de données statique.
using namespace std::literals;
struct matrix_constants
{
template<class T>
using pauli = hermitian_matrix<T, 2>; // alias de template
template<class T> // membre de données statique template
static constexpr pauli<T> sigmaX = {{0, 1}, {1, 0}};
template<class T>
static constexpr pauli<T> sigmaY = {{0, -1i}, {1i, 0}};
template<class T>
static constexpr pauli<T> sigmaZ = {{1, 0}, {0, -1}};
};
Comme pour les autres
membres statiques
, une définition d'un modèle de membre de données statique peut être requise. Cette définition est fournie en dehors de la définition de la classe. Une déclaration de modèle de membre de données statique au niveau de la portée du namespace peut également être une définition d'un
membre de données non-modèle d'un modèle de classe
:
struct limits
{
template<typename T>
static const T min; // déclaration d'un membre de données statique template
};
template<typename T>
const T limits::min = { }; // définition d'un membre de données statique template
template<class T>
class X
{
static T s; // déclaration d'un membre de données statique non-template d'une classe template
};
template<class T>
T X<T>::s = 0; // définition d'un membre de données non-template d'une classe template
À moins qu'un modèle de variable n'ait été
explicitement spécialisé
ou explicitement instancié, il est implicitement instancié lorsqu'une spécialisation du modèle de variable est référencée dans un contexte qui nécessite
qu'une définition de variable existe
ou si l'existence de la définition affecte la sémantique du programme, c'est-à-dire si la variable est
nécessaire pour l'évaluation constante
par une expression (la définition peut ne pas être utilisée).
L'existence d'une définition d'une variable est considérée comme affectant la sémantique du programme si la variable est nécessaire pour l'évaluation constante par une expression, même si l'évaluation constante de l'expression n'est pas requise ou si l'évaluation d'expression constante n'utilise pas la définition.
Notes
Jusqu'à ce que les modèles de variables soient introduits en C++14, les variables paramétrées étaient généralement implémentées soit comme des membres de données statiques de modèles de classe, soit comme des modèles de fonction constexpr renvoyant les valeurs souhaitées.
Les modèles de variables ne peuvent pas être utilisés comme
arguments de modèle de modèle
.
Rapports de défauts
Les rapports de défauts modifiant le comportement suivants ont été appliqués rétroactivement aux normes C++ précédemment publiées.
|
DR
|
Appliqué à
|
Comportement publié
|
Comportement correct
|
|
CWG 2255
|
C++14
|
il n'était pas clair si une spécialisation d'un modèle
de données membre statique est une donnée membre statique
|
elle l'est
|