Ver Mensaje Individual
  #2 (permalink)  
Antiguo 28/09/2015, 03:21
eferion
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 9 años, 6 meses
Puntos: 204
Respuesta: Escrudiñando el api de C++

typedef sirve para definir un alias:

Código C++:
Ver original
  1. typedef unsigned int miUint;
  2. miUint dato; // el tipo real de dato es unsigned int

A partir del estándar C++11 también se puede usar using:

Código C++:
Ver original
  1. using miUint = unsigned int;
  2. miUint dato; // el tipo real de dato es unsigned int

por otro lado, lo que se está intentando en esa línea es asignar un alias basándose en un tipo que proviene de un template.

Para explicarlo voy a usar un ejemplo tonto ad-hoc.

imagínate que tienes una colección de clases que, entre otras cosas, cada una te proporciona un tipo de dato de la siguiente forma:

Código C++:
Ver original
  1. struct dummy1
  2. {
  3.   typedef char tipoConcreto;
  4. };
  5.  
  6. struct dummy2
  7. {
  8.   typedef int tipoConcreto;
  9. };

Ahora imagina que necesitas crear un template que ha de tener una variable cuyo tipo ha de coincidir con el de un tipoConcreto en particular. Un primer acercamiento podría ser:

Código C++:
Ver original
  1. template<typename T>
  2. struct TypeTemplate
  3. {
  4.   typedef T::tipoConcreto t;
  5.  
  6.   t variable;
  7. };

pero claro, si intentamos usar este template directamente en nuestro código nos encontraremos con un bonito error de compilación. El problema es que T::tipoConcreto no es un nombre cualificado, es dependiente de la especialización que usemos. En estos casos necesitamos usar typename. Tómalo como una protección que te exige el compilador para asegurarse de que sabes lo que estás haciendo.

Código C++:
Ver original
  1. template<typename T>
  2. struct TypeTemplate
  3. {
  4.   typedef typename T::tipoConcreto t;
  5.  
  6.   t variable;
  7. };

Ahora ya no da errores de compilación y podemos probar nuestro código:

Código C++:
Ver original
  1. int main()
  2. {
  3.   TypeTemplate<dummy1> miTemplate1;
  4.   TypeTemplate<dummy2> miTemplate2;
  5.   miTemplate1.variable = 60;
  6.   miTemplate2.variable = 60;
  7.  
  8.   std::cout << miTemplate1.variable << " " << miTemplate2.variable;
  9. }

La salida del programa será:

Código :
Ver original
  1. < 60

En primer lugar ha imprimido un carácter, puesto que dummy1::tipoConcreto es de tipo char. Concretamente ha imprimido el carácter 60. A continuación imprime un entero, ya que dummy2::tipoConcreto es de tipo int.

Espero que con este ejemplo haya quedado resuelta la duda.

Un saludo.