Type alias, alias template (since C++11)
Typalias ist ein Name, der sich auf einen zuvor definierten Typ bezieht (ähnlich wie
typedef
).
Alias-Vorlage ist ein Name, der sich auf eine Familie von Typen bezieht.
Inhaltsverzeichnis |
Syntax
Alias-Deklarationen sind Deklarationen mit der folgenden Syntax:
using
Bezeichner
attr
(optional)
=
Typ-ID
;
|
(1) | ||||||||
template
<
Template-Parameter-Liste
>
|
(2) | ||||||||
template
<
Template-Parameter-Liste
>
requires
Constraint
|
(3) | (seit C++20) | |||||||
| attr | - | optionale Sequenz beliebig vieler Attribute |
| identifier | - | der durch diese Deklaration eingeführte Name, der entweder ein Typname (1) oder ein Templatename (2) wird |
| template-parameter-list | - | Template-Parameterliste , wie in Template-Deklaration |
| constraint | - | ein Constraint-Ausdruck , der die von diesem Alias-Template akzeptierten Template-Parameter einschränkt |
| type-id | - | abstrakter Deklarator oder ein anderer gültiger Typ-Bezeichner (der einen neuen Typ einführen kann, wie in Typ-Bezeichner beschrieben). Der Typ-Bezeichner darf nicht direkt oder indirekt auf identifier verweisen. Beachten Sie, dass der Deklarationspunkt des Identifikators beim Semikolon nach type-id liegt. |
Erklärung
template<class T> struct Alloc {}; template<class T> using Vec = vector<T, Alloc<T>>; // type-id ist vector<T, Alloc<T>> Vec<int> v; // Vec<int> ist dasselbe wie vector<int, Alloc<int>>
Wenn das Ergebnis der Spezialisierung eines Alias-Templates eine abhängige template-id ist, werden nachfolgende Substitutionen auf diese template-id angewendet:
template<typename...> using void_t = void; template<typename T> void_t<typename T::foo> f(); f<int>(); // Fehler, int hat keinen geschachtelten Typ foo
Der bei der Spezialisierung eines Alias-Templates erzeugte Typ darf nicht direkt oder indirekt seinen eigenen Typ verwenden:
template<class T> struct A; template<class T> using B = typename A<T>::U; // type-id ist A<T>::U template<class T> struct A { typedef B<T> U; }; B<short> b; // Fehler: B<short> verwendet seinen eigenen Typ über A<short>::U
Alias-Templates werden niemals durch Template-Argument-Deduktion abgeleitet, wenn ein Template-Template-Parameter abgeleitet wird.
Es ist nicht möglich, ein Alias-Template partiell oder explizit zu spezialisieren .Wie jede Template-Deklaration kann ein Alias-Template nur im Klassenbereich oder Namensbereich deklariert werden.
|
Der Typ eines Lambda-Ausdrucks , der in einer Alias-Template-Deklaration erscheint, unterscheidet sich zwischen Instanziierungen dieses Templates, selbst wenn der Lambda-Ausdruck nicht abhängig ist. template<class T> using A = decltype([] {}); // A<int> and A<char> refer to different closure types |
(seit C++20) |
Hinweise
| Feature-Test-Makro | Wert | Std | Feature |
|---|---|---|---|
__cpp_alias_templates
|
200704L
|
(C++11) | Alias-Templates |
Schlüsselwörter
Beispiel
#include <iostream> #include <string> #include <type_traits> #include <typeinfo> // Typalias, identisch zu // typedef std::ios_base::fmtflags flags; using flags = std::ios_base::fmtflags; // der Name 'flags' bezeichnet nun einen Typ: flags fl = std::ios_base::dec; // Typalias, identisch zu // typedef void (*func)(int, int); using func = void (*) (int, int); // der Name 'func' bezeichnet nun einen Funktionszeiger: void example(int, int) {} func f = example; // Alias-Template template<class T> using ptr = T*; // der Name 'ptr<T>' ist nun ein Alias für Zeiger auf T ptr<int> x; // Typalias zur Verdeckung eines Template-Parameters template<class CharT> using mystring = std::basic_string<CharT, std::char_traits<CharT>>; mystring<char> str; // Typalias kann einen Member-Typedef-Namen einführen template<typename T> struct Container { using value_type = T; }; // kann in generischer Programmierung verwendet werden template<typename ContainerT> void info(const ContainerT& c) { typename ContainerT::value_type T; std::cout << "ContainerT is `" << typeid(decltype(c)).name() << "`\n" "value_type is `" << typeid(T).name() << "`\n"; } // Typalias zur Vereinfachung der Syntax von std::enable_if template<typename T> using Invoke = typename T::type; template<typename Condition> using EnableIf = Invoke<std::enable_if<Condition::value>>; template<typename T, typename = EnableIf<std::is_polymorphic<T>>> int fpoly_only(T) { return 1; } struct S { virtual ~S() {} }; int main() { Container<int> c; info(c); // Container::value_type wird in dieser Funktion int sein // fpoly_only(c); // Fehler: enable_if verbietet dies S s; fpoly_only(s); // okay: enable_if erlaubt dies }
Mögliche Ausgabe:
ContainerT is `struct Container<int>` value_type is `int`
Fehlerberichte
Die folgenden verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.
| DR | Angewendet auf | Verhalten wie veröffentlicht | Korrektes Verhalten |
|---|---|---|---|
| CWG 1558 | C++11 |
ob ungenutzte Argumente in einer Alias-Spezialisierung
an der Substitution teilnehmen, war nicht spezifiziert |
Substitution
wird durchgeführt |
Siehe auch
typedef
Deklaration
|
erzeugt ein Synonym für einen Typ |
| Namespace-Alias | erzeugt einen Alias für einen existierenden Namespace |