Alias de tipo, plantilla de alias (desde C++11)
Alias de tipo es un nombre que se refiere a un tipo definido anteriormente (parecido a typedef).
Plantilla de alias es un nombre que se refiere a una familia de tipos.
Contenido |
[editar] Sintaxis
Declaraciones de alias son declaraciones con la sintaxis siguiente:
using identificador attr(opcional) = id-tipo ;
|
(1) | ||||||||
template < lista-parámetros-plantilla >
|
(2) | ||||||||
attr | - | secuencia opcional de cualquier número de atributos |
identificador | - | el nombre creado en la declaración, que se convierte en un nombre de tipo (1) o plantilla (2) |
lista-parámetros-plantilla | - | lista de parámetros de plantilla, como en una declaración de plantilla |
id-tipo | - | declarador abstracto o cualquier otro tid-tipo válido (que puede introducir un nuevo tipo, como se indica en id-tipo). El id-tipo no puede hacer referencia directamente ni indirectamente al identificador. Tenga en cuenta que el punto de declaración del identificador está en el punto y coma que va después de id-tipo. |
[editar] Explicación
template<class T> struct Alloc { }; template<class T> using Vec = vector<T, Alloc<T> >; // el id-tipo es vector<T, Alloc<T> > Vec<int> v; // Vec<int> es lo mismo que vector<int, Alloc<int> >
Cuando el resultado de especializar una plantilla de alias es un id-plantilla dependiente, se aplican sustituciones posteriores a ese id-plantilla:
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 tiene permitido usar su propio tipo directa o indirectamente:
template<class T> struct A; template<class T> using B = typename A<T>::U; // el id-tipo es A<T>::U template<class T> struct A { typedef B<T> U; }; B<short> b; // error: B<short> usa su propio tipo a través de A<short>::U
Las plantillas de alias nunca se calculan mediante la deducción de argumentos de plantilla al inferir un parámetro de plantilla de plantilla.
No es posible especializar una plantilla de alias parcial o explícitamente.Como cualquier declaración de plantilla, una plantilla de alias solo se puede declarar en un ámbito de clase o espacio de nombres.
El tipo de una expresión lambda que aparece en una declaración de plantilla de alias es diferente entre instancias de esa plantilla, incluso cuando la expresión lambda no es dependiente. template <class T> using A = decltype([] { }); // A<int> y A<char> hacen referencia a diferentes tipos |
(desde C++20) |
[editar] Ejemplo
#include <string> #include <ios> #include <type_traits> // alias de tipo, lo mismo que // typedef std::ios_base::fmtflags flags; using flags = std::ios_base::fmtflags; // el nombre 'flags' indica ahora un tipo: flags fl = std::ios_base::dec; // alias de tipo, igual a // typedef void (*func)(int, int); using func = void (*) (int, int); // el nombre 'func' indica ahora 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>' ahora es un alias de 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; // el alias de tipo puede introducir un nombre typedef de miembro template<typename T> struct Container { using value_type = T; }; // que se puede usar en programación general template<typename ContainerType> void g(const ContainerType& c) { typename ContainerType::value_type 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 t) { return 1; } struct S { virtual ~S() {} }; int main() { Container<int> c; g(c); // Container::value_type será int en esta función // fpoly_only(c); // error: enable_if no permite sto S s; fpoly_only(s); // correcto: enable_if permite esto }
A
[editar] Informe de errores
Los siguientes informes de defectos de cambio de comportamiento se aplicaron de manera retroactiva a los estándares de C++ publicados anteriormente.
ID | Aplicado a | Comportamiento según lo publicado | Comportamiento correcto |
---|---|---|---|
CWG 1558 | C++11 | No se especifica si los argumentos no utilizados en una especialización de alias participan en la substitición | Se realiza la sustitución |
[editar] Ver también
declaración typedef | crea un sinónimo para un tipo
Original: creates a synonym for a type The text has been machine-translated via Google Translate. You can help to correct and verify the translation. Click here for instructions. |
Alias de espacios de nombres | Crea un alias de un espacio de nombres existente. |