Type alias, alias template (since C++11)
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
>
|
(2) | ||||||||
template
<
template-parameter-list
>
requires
constraint
|
(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
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
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 |