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

Un alias de tipo es un nombre que se refiere a un tipo previamente definido (similar a typedef ).

La plantilla de alias es un nombre que se refiere a una familia de tipos.

Contenidos

Sintaxis

Las declaraciones de alias son declaraciones con la siguiente sintaxis:

using identificador attr  (opcional) = type-id ; (1)
template < template-parameter-list >

using identificador attr  (opcional) = type-id ;

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

using identificador attr  (opcional) = type-id ;

(3) (desde C++20)
attr - secuencia opcional de cualquier número de atributos
identifier - el nombre introducido por esta declaración, que se convierte en un nombre de tipo (1) o un nombre de plantilla (2)
template-parameter-list - lista de parámetros de plantilla , como en declaración de plantilla
constraint - una expresión de restricción que restringe los parámetros de plantilla aceptados por esta plantilla de alias
type-id - declarador abstracto o cualquier otro type-id válido (que puede introducir un nuevo tipo, como se señala en type-id ). El type-id no puede referirse directa o indirectamente a identifier . Nótese que el punto de declaración del identificador está en el punto y coma que sigue a type-id .

Explicación

1) Una declaración de alias de tipo introduce un nombre que puede utilizarse como sinónimo del tipo denotado por type-id . No introduce un nuevo tipo y no puede cambiar el significado de un nombre de tipo existente. No hay diferencia entre una declaración de alias de tipo y una declaración typedef . Esta declaración puede aparecer en ámbito de bloque, ámbito de clase o ámbito de espacio de nombres.
2) Una plantilla de alias es una plantilla que, cuando se especializa, es equivalente al resultado de sustituir los argumentos de la plantilla de alias por los parámetros de plantilla en el type-id .
template<class T>
struct Alloc {};
template<class T>
using Vec = vector<T, Alloc<T>>; // type-id es vector<T, Alloc<T>>
Vec<int> v; // Vec<int> es igual que vector<int, Alloc<int>>

Cuando el resultado de especializar una plantilla de alias es un template-id dependiente, las sustituciones posteriores se aplican a ese template-id:

template<typename...>
using void_t = void;
template<typename T>
void_t<typename T::foo> f();
f<int>(); // error, int no tiene un tipo anidado foo

El tipo producido al especializar una plantilla de alias no puede utilizar directa o indirectamente su propio tipo:

template<class T>
struct A;
template<class T>
using B = typename A<T>::U; // type-id es A<T>::U
template<class T>
struct A { typedef B<T> U; };
B<short> b; // error: B<short> utiliza su propio tipo mediante A<short>::U

Las plantillas de alias nunca son deducidas por template argument deduction al deducir un parámetro de plantilla de plantilla.

No es posible especializar parcialmente o especializar explícitamente una plantilla de alias.

Como cualquier declaración de plantilla, una plantilla de alias solo puede declararse en el ámbito de clase o en el ámbito de espacio de nombres.

El tipo de una expresión lambda que aparece en una declaración de plantilla de alias es diferente entre instanciaciones de esa plantilla, incluso cuando la expresión lambda no es dependiente.

template<class T>
using A = decltype([] {}); // A<int> and A<char> refer to different closure types
(desde C++20)

Notas

Macro de prueba de características Valor Std Característica
__cpp_alias_templates 200704L (C++11) Alias templates

Palabras clave

using

Ejemplo

#include <iostream>
#include <string>
#include <type_traits>
#include <typeinfo>
// alias de tipo, idéntico a
// typedef std::ios_base::fmtflags flags;
using flags = std::ios_base::fmtflags;
// el nombre 'flags' ahora denota un tipo:
flags fl = std::ios_base::dec;
// alias de tipo, idéntico a
// typedef void (*func)(int, int);
using func = void (*) (int, int);
// el nombre 'func' ahora denota un puntero a función:
void example(int, int) {}
func f = example;
// plantilla de alias
template<class T>
using ptr = T*;
// el nombre 'ptr<T>' es ahora un alias para puntero a T
ptr<int> x;
// alias de tipo usado para ocultar un parámetro de plantilla
template<class CharT>
using mystring = std::basic_string<CharT, std::char_traits<CharT>>;
mystring<char> str;
// un alias de tipo puede introducir un nombre typedef miembro
template<typename T>
struct Container { using value_type = T; };
// que puede usarse en programación genérica
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";
}
// alias de tipo usado para simplificar la sintaxis de 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 será int en esta función
//  fpoly_only(c); // error: enable_if prohíbe esto
    S s;
    fpoly_only(s); // correcto: enable_if permite esto
}

Salida posible:

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

Informes de defectos

Los siguientes informes de defectos que modifican el comportamiento se aplicaron retroactivamente a los estándares de C++ publicados anteriormente.

DR Applied to Behavior as published Correct behavior
CWG 1558 C++11 no se especificaba si los argumentos no utilizados en una especialización de alias
participaban en la sustitución
la sustitución
se realiza

Véase también

typedef declaración crea un sinónimo para un tipo
alias de namespace crea un alias de un namespace existente