studio programacion para móviles libros gratis español edición desarrollo desarrollar curso aprende aplicaciones c++ templates c++11 typedef template-aliases

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 de std::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 clave using 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 especificador typedef . 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.