3.2.1e typename
§1 Sinopsis
La palabra clave typename es un especificador de tipo. Indica justamente eso, que el identificador que la acompaña es un tipo (aunque no se haya definido todavía). Una especie de declaración adelantada para que el compilador no lo rechace (al identificador) y lo tome como tal.
§2 Sintaxis
Son posibles dos formas:
typename identificador §2a
template < typename identificador > identificador-de-clase §2b
§3 Comentario
La forma §2a se utiliza para declarar variables que no han sido definidas todavía. De esta forma se evita que el compilador genere un error avisando que es un "tipo no definido". En el siguiente ejemplo se utiliza esta sintaxis para utilizar miembros A de una clase T ( T::A ) que no ha sido definida todavía:
template <class T> // clase T no definida aún
void f() {
typedef typename T::A TA; // L.3 declara TA como tipo T::A
TA
a1;
// L.4 declara a1 como de tipo TA
typename T::A a2; //
declara a2 como de tipo T::A
TA * ptra;
// declara ptra como puntero-a-TA
}
L.3 especifica que cada ocurrencia de TA será sustituida por typename T::A, lo que significa que por ejemplo, la sentencia L.4 es vista por el compilador como: typename T::A a1;.
La sintaxis §2b se utiliza en sustitución de la palabra clave class en las declaraciones de plantillas ( 4.12.2). El sentido es el mismo; significa "este argumento es cualquier tipo". En el siguiente ejemplo se utiliza esta sintaxis en la declaración de dos funciones genéricas:
template <typename T1, typename T2> T2 convert (T1 t1) { // L.1
return (T2)t1;
}
template <typename X, class Y> bool isequal (X x, Y y) { // L.5
if (x==y)return 1; return 0;
}
Observe que la definición L.1 utiliza typename en sustitución del
especificador class, mientras que en L.5 se utilizan indistintamente.