Namespaces
Variants

Type alias, alias template (since C++11)

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

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 >

using Bezeichner attr  (optional) = Typ-ID ;

(2)
template < Template-Parameter-Liste > requires Constraint

using Bezeichner attr  (optional) = Typ-ID ;

(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

1) Eine Typalias-Deklaration führt einen Namen ein, der als Synonym für den durch type-id bezeichneten Typ verwendet werden kann. Sie führt keinen neuen Typ ein und kann die Bedeutung eines bestehenden Typnamens nicht ändern. Es gibt keinen Unterschied zwischen einer Typalias-Deklaration und einer typedef -Deklaration. Diese Deklaration kann im Blockbereich, Klassenbereich oder Namensraumbereich erscheinen.
2) Ein Alias-Template ist ein Template, das bei Spezialisierung dem Ergebnis der Substitution der Template-Argumente des Alias-Templates für die Template-Parameter in der type-id entspricht.
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

using

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