Oficialmente, ¿para qué sirve typename? [duplicar]
En ocasiones he visto algunos mensajes de error realmente indescifrables al gcc
usar plantillas... Específicamente, he tenido problemas en los que declaraciones aparentemente correctas causaban errores de compilación muy extraños que mágicamente desaparecían al anteponer la typename
palabra clave al principio del declaración... (Por ejemplo, la semana pasada, estaba declarando dos iteradores como miembros de otra clase con plantilla y tuve que hacer esto)...
¿Cuál es la historia typename
?
La siguiente es la cita del libro de Josutti:
La palabra clave
typename
se introdujo para especificar que el identificador que sigue es un tipo. Considere el siguiente ejemplo:
template <class T> Class MyClass { typename T::SubType * ptr; ... };
Aquí
typename
se utiliza para aclarar queSubType
es un tipo declass T
. Por tanto,ptr
es un puntero al tipoT::SubType
. Sintypename
,SubType
se consideraría un miembro estático. De este modoT::SubType * ptr
sería una multiplicación del valor
SubType
del tipoT
conptr
.
La publicación del blog de Stan Lippman sugiere:
Stroustrup reutilizó la palabra clave de clase existente para especificar un parámetro de tipo en lugar de introducir una nueva palabra clave que, por supuesto, podría romper los programas existentes. No es que no se considerara una nueva palabra clave, simplemente que no se consideró necesaria dada su potencial disrupción. Y hasta el estándar ISO-C++, esta era la única forma de declarar un parámetro de tipo.
Básicamente, Stroustrup reutilizó la palabra clave class sin introducir una nueva palabra clave que luego se cambia en el estándar por las siguientes razones.
Como el ejemplo dado
template <class T>
class Demonstration {
public:
void method() {
T::A *aObj; // oops …
// …
};
la gramática del idioma se malinterpreta T::A *aObj;
como una expresión aritmética, por lo que se introduce una nueva palabra clave llamada typename
:
typename T::A* a6;
Le indica al compilador que trate la declaración posterior como una declaración.
Dado que la palabra clave estaba en la nómina, diablos, ¿por qué no solucionar la confusión causada por la decisión original de reutilizar la palabra clave de clase?
por eso tenemos ambos.
Puedes echarle un vistazo a este post . Definitivamente te ayudará. Simplemente extraje todo lo que pude.
Considere el código
template<class T> somefunction( T * arg )
{
T::sometype x; // broken
.
.
Desafortunadamente, no es necesario que el compilador sea psíquico y no sabe si T::sometype terminará refiriéndose a un nombre de tipo o a un miembro estático de T. Por lo tanto, se suele typename
decir:
template<class T> somefunction( T * arg )
{
typename T::sometype x; // works!
.
.