c++ - programacion - ¿Cuál fue el problema resuelto por la nueva sintaxis de "uso" para los typedefs de plantillas?
manual programacion android español pdf (4)
En C ++ 11 puedes crear un "alias de tipo" haciendo algo como
template <typename T>
using stringpair = std::pair<std::string, T>;
Pero esto es una desviación de lo que cabría esperar que se vería una plantilla typedef:
template <typename T>
typedef std::pair<std::string, T> stringpair;
Entonces, esto plantea la pregunta: ¿por qué tuvieron que crear una nueva sintaxis? ¿Qué fue lo que no funcionó con la sintaxis de typedef
?
Me doy cuenta de que el último bit no se compila, pero ¿por qué no se puede compilar?
De los apodos de la plantilla N1489 de la propuesta WG21 (por Stroustrup y Dos Reis):
Se ha sugerido (re) usar la palabra clave
typedef
como se hace en el documento [4] para introducir alias de plantillas:
template<class T> typedef std::vector<T, MyAllocator<T> > Vec;
Esa notación tiene la ventaja de utilizar una palabra clave ya conocida para introducir un alias de tipo. Sin embargo, también muestra varias desventajas entre las que se encuentra la confusión de utilizar una palabra clave para introducir un alias para un nombre de tipo en un contexto en el que el alias no designa un tipo, sino una plantilla; Vec no es un alias para un tipo, y no debe tomarse para un typedef-name. El nombre Vec es un nombre para la familia
std::vector<o, MyAllocator<o> >
donde la viñeta es un marcador de posición para un nombre de tipo. En consecuencia no proponemos la sintaxis typedef.Por otro lado la frase
template<class T> using Vec = std::vector<T, MyAllocator<T> >;
se puede leer / interpretar como: de ahora en
std::vector<T, MyAllocator<T> >
Vec<T>
como sinónimo destd::vector<T, MyAllocator<T> >
. Con esa lectura, la nueva sintaxis para el alias parece razonablemente lógica.
El documento [4] al que se hace referencia en la cita anterior fue una propuesta previa WG21 N1406 Adición propuesta a C ++: Plantillas Typedef (por Herb Sutter). Utiliza una sintaxis diferente ( typedef
vs using
), así como una nomenclatura diferente (typedef templates vs template aliases). La sintaxis propuesta por Herb no lo logró, pero la nomenclatura a veces se puede encontrar en discusiones informales.
Me referiré a stroustrup mismo:
http://www.stroustrup.com/C++11FAQ.html#template-alias
La palabra clave using se usa para obtener una notación lineal "nombre seguido de a qué se refiere". Probamos con la solución typedef convencional y complicada, pero nunca logramos obtener una solución completa y coherente hasta que nos decidimos por una sintaxis menos oscura.
Una razón más para la nueva sintaxis: typedefs para funciones, arrays y construcciones similares se vuelve un poco más comprensible.
Referencia a la matriz antes / después:
typedef int(&my_type)[3];
using my_type = int(&)[3];
Matriz de punteros de función antes / después:
typedef void(*my_type[3])();
using my_type = void(*[3])();
(tl; dr: using
plantillas de soporte, mientras que typedef
no).
Como suena como ya sabes, la diferencia entre los dos ejemplos sin plantillas no es nada:
[C++11: 7.1.3/2]:
También puede introducirse un typedef-name mediante una declaración de alias . El identificador que sigue a la palabra claveusing
convierte en un typedef-name y el atributo opcional -especificador-seq que sigue al identificador pertenece a ese typedef-name . Tiene la misma semántica que si fuera introducida por el especificadortypedef
. En particular, no define un nuevo tipo y no aparecerá en el ID de tipo .
Sin embargo, la plantilla typedef
s no existe!
[C++11: 14.5.7/1]:
Una declaración de plantilla en la que la declaración es una declaración de alias (Cláusula 7) declara que el identificador es una plantilla de alias. Una plantilla de alias es un nombre para una familia de tipos. El nombre de la plantilla de alias es un nombre de plantilla .
¿Por qué simplemente no reutilizaron la sintaxis de typedef
? Bueno, creo que typedef
es simplemente el estilo "antiguo" y, dado el uso del using
en otros contextos, se decidió que la nueva funcionalidad debería tomar la forma de using
para mantener la coherencia.