Namensräume
Varianten
Aktionen

Typalias, Alias-Template (seit C++11)

Von cppreference.com
< cpp‎ | Sprache
 
 
C++ Sprache
Allgemeine Themen
Kontrollfluss
Bedingte Ausführungsaussagen
if
Iterationsanweisungen (Schleifen)
for
Bereichs-for (C++11)
Sprunganweisungen
Funktionen
Funktionsdeklaration
Lambda-Funktionsausdruck
inline-Spezifizierer
Dynamische Ausnahmespezifikationen (bis C++17*)
noexcept-Spezifizierer (C++11)
Ausnahmen
Namensräume
Typen
Spezifizierer
const/volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Speicherdauer-Spezifizierer
Initialisierung
Ausdrücke
Alternative Darstellungen
Literale
Boolesch - Ganzzahl - Gleitkommazahl
Zeichen - String - nullptr (C++11)
Benutzerdefinierte (C++11)
Dienstprogramme
Attribute (C++11)
Typen
typedef-Deklaration
Typalias-Deklaration (C++11)
Umwandlungen
Speicherzuweisung
Klassen
Klassenspezifische Funktionseigenschaften
explicit (C++11)
static

Spezielle Member-Funktionen
Templates
Sonstiges
 
 

Ein Typalias ist ein Name, der sich auf einen zuvor definierten Typ bezieht (ähnlich wie typedef).

Ein Alias-Template ist ein Name, der sich auf eine Familie von Typen bezieht.

Inhalt

[bearbeiten] Syntax

Alias-Deklarationen sind Deklarationen mit der folgenden Syntax

using identifier attr (optional) = type-id ; (1)
template < template-parameter-list >

using identifier attr (optional) = type-id ;

(2)
template < template-parameter-list > requires constraint

using identifier attr (optional) = type-id ;

(3) (seit C++20)
attr - optionale Sequenz von beliebig vielen Attributen
identifier - der durch diese Deklaration eingeführte Name, der entweder ein Typname (1) oder ein Template-Name (2) wird
template-parameter-list - Template-Parameterliste, wie in Template-Deklaration
constraint - ein Constraint-Ausdruck, der die vom Alias-Template akzeptierten Template-Parameter einschränkt
type-id - abstrakter Deklarator oder ein anderer gültiger type-id (der einen neuen Typ einführen kann, wie in type-id vermerkt). Der type-id darf sich nicht direkt oder indirekt auf identifier beziehen. Beachten Sie, dass der Deklarationspunkt des Identifiers das Semikolon nach type-id ist.

[bearbeiten] Erklärung

1) Eine Typalias-Deklaration führt einen Namen ein, der als Synonym für den vom 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 Block-Scope, Klassen-Scope oder Namensraum-Scope auftreten.
2) Ein Alias-Template ist ein Template, das bei Spezialisierung äquivalent zum Ergebnis der Ersetzung der Template-Argumente des Alias-Templates für die Template-Parameter im type-id ist.
template<class T>
struct Alloc {};
 
template<class T>
using Vec = vector<T, Alloc<T>>; // type-id is vector<T, Alloc<T>>
 
Vec<int> v; // Vec<int> is the same as vector<int, Alloc<int>>

Wenn das Ergebnis der Spezialisierung eines Alias-Templates ein abhängiges template-id ist, werden nachfolgende Ersetzungen auf dieses template-id angewendet.

template<typename...>
using void_t = void;
 
template<typename T>
void_t<typename T::foo> f();
 
f<int>(); // error, int does not have a nested type foo

Der Typ, der bei der Spezialisierung eines Alias-Templates erzeugt wird, darf seinen eigenen Typ nicht direkt oder indirekt verwenden.

template<class T>
struct A;
 
template<class T>
using B = typename A<T>::U; // type-id is A<T>::U
 
template<class T>
struct A { typedef B<T> U; };
 
B<short> b; // error: B<short> uses its own type via 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 Klassen-Scope oder Namensraum-Scope deklariert werden.

Der Typ eines Lambda-Ausdrucks, der in einer Alias-Template-Deklaration vorkommt, ist zwischen Instanziierungen dieses Templates unterschiedlich, auch 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)

[bearbeiten] Hinweise

Feature-Testmakro Wert Std Feature
__cpp_alias_templates 200704L (C++11) Alias-Templates

[bearbeiten] Schlüsselwörter

using

[bearbeiten] Beispiel

#include <iostream>
#include <string>
#include <type_traits>
#include <typeinfo>
 
// type alias, identical to
// typedef std::ios_base::fmtflags flags;
using flags = std::ios_base::fmtflags;
// the name 'flags' now denotes a type:
flags fl = std::ios_base::dec;
 
// type alias, identical to
// typedef void (*func)(int, int);
using func = void (*) (int, int);
 
// the name 'func' now denotes a pointer to function:
void example(int, int) {}
func f = example;
 
// alias template
template<class T>
using ptr = T*;
// the name 'ptr<T>' is now an alias for pointer to T
ptr<int> x;
 
// type alias used to hide a template parameter
template<class CharT>
using mystring = std::basic_string<CharT, std::char_traits<CharT>>;
 
mystring<char> str;
 
// type alias can introduce a member typedef name
template<typename T>
struct Container { using value_type = T; };
 
// which can be used in generic programming
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";
}
 
// type alias used to simplify the syntax of 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 will be int in this function
//  fpoly_only(c); // error: enable_if prohibits this
    S s;
    fpoly_only(s); // okay: enable_if allows this
}

Mögliche Ausgabe

ContainerT is `struct Container<int>`
value_type is `int`

[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 1558 C++11 ob ungenutzte Argumente in einer Alias-Spezialisierung
an der Ersetzung teilnehmen, war nicht spezifiziert
substitution
wird durchgeführt

[bearbeiten] Siehe auch

typedef-Deklaration erstellt ein Synonym für einen Typ[bearbeiten]
Namespace-Alias erstellt einen Alias für einen vorhandenen Namespace[bearbeiten]