Variable template (seit C++14)
Ein Variablentemplate definiert eine Familie von Variablen oder statischen Datenmembern.
Inhalt |
[bearbeiten] Syntax
template < parameter-list > variable-declaration |
(1) | ||||||||
template < parameter-list > requires constraint variable-declaration |
(2) | (seit C++20) | |||||||
| variable-declaration | - | eine Deklaration einer Variablen. Der deklarierte Variablenname wird zu einem Template-Namen. |
| parameter-liste | - | eine nicht-leere, durch Kommas getrennte Liste der Template-Parameter, von denen jeder entweder ein Nicht-Typ-Parameter, ein Typ-Parameter, ein Template-Parameter oder ein Parameter-Pack aus beliebigen dieser ist. |
| constraint | - | ein Constraint-Ausdruck, der die vom Variablentemplate akzeptierten Template-Parameter einschränkt |
[bearbeiten] Erklärung
Eine aus einem Variablentemplate instanziierte Variable wird als instanziierte Variable bezeichnet. Ein aus einem Datenmember-Template instanziierter statischer Datenmember wird als instanziierter statischer Datenmember bezeichnet.
Ein Variablentemplate kann durch eine Template-Deklaration im Namespace-Scope eingeführt werden, wobei variable-declaration eine Variable deklariert.
template<class T> constexpr T pi = T(3.1415926535897932385L); // variable template template<class T> T circular_area(T r) // function template { return pi<T> * r * r; // pi<T> is a variable template instantiation }
Wenn es im Klassen-Scope verwendet wird, deklariert ein Variablentemplate ein Template für statische Datenmember.
using namespace std::literals; struct matrix_constants { template<class T> using pauli = hermitian_matrix<T, 2>; // alias template template<class T> // static data member 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}}; };
Wie bei anderen statischen Membern kann eine Definition eines Template für statische Datenmember erforderlich sein. Eine solche Definition wird außerhalb der Klassendefinition bereitgestellt. Eine Template-Deklaration eines statischen Datenmembers im Namespace-Scope kann auch eine Definition eines nicht-Template- Datenmembers einer Klassentemplate sein.
struct limits { template<typename T> static const T min; // declaration of a static data member template }; template<typename T> const T limits::min = { }; // definition of a static data member template template<class T> class X { static T s; // declaration of a non-template static data member of a class template }; template<class T> T X<T>::s = 0; // definition of a non-template data member of a class template
Es sei denn, ein Variablentemplate wurde explizit spezialisiert oder explizit instanziiert, wird es implizit instanziiert, wenn eine Spezialisierung des Variablentemplates in einem Kontext referenziert wird, der eine Variablendefinition erfordert, oder wenn die Existenz der Definition die Semantik des Programms beeinflusst, d.h. wenn die Variable für die Konstantenbewertung durch einen Ausdruck benötigt wird (die Definition wird möglicherweise nicht verwendet).
Die Existenz einer Variablendefinition gilt als Beeinflussung der Programmsemantik, wenn die Variable für die Konstantenbewertung durch einen Ausdruck benötigt wird, auch wenn die Konstantenbewertung des Ausdrucks nicht erforderlich ist oder wenn die Konstantenbewertung die Definition nicht verwendet.
[bearbeiten] Hinweise
Bis zur Einführung von Variablentemplates in C++14 wurden parametrisierte Variablen typischerweise entweder als statische Datenmember von Klassentemplates oder als Konstanten-Funktionstemplates, die die gewünschten Werte zurückgeben, implementiert.
Variablentemplates können nicht als Template-Template-Argumente verwendet werden.
| Feature-Testmakro | Wert | Std | Feature |
|---|---|---|---|
__cpp_variable_templates |
201304L |
(C++14) | Variablentemplates |
[bearbeiten] Defect reports
Die folgenden Verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.
| DR | angewendet auf | Verhalten wie veröffentlicht | Korrigiertes Verhalten |
|---|---|---|---|
| CWG 2255 | C++14 | war unklar, ob eine Spezialisierung eines statischen Datenmember-Templates ein statischer Datenmember ist |
sie ist |