La palabra clave typename en C++
- Nombres calificados y no calificados en C++
- Nombres dependientes y no dependientes en C++
-
Uso de la palabra clave
typename
en C++
![La palabra clave typename en C++](/img/Cpp/feature-image---typename-keyword-in-cpp.webp)
Este artículo discutirá la palabra clave typename
en C++.
Para comprender el significado de la palabra clave typename
, debemos comprender los conceptos clave de los nombres cualificados
y dependientes
.
Nombres calificados y no calificados en C++
Un nombre calificado especifica un ámbito. Veamos un ejemplo para entenderlo mejor.
#include <bits/stdc++.h>
int main() { std::cout << "Hello world!" << std::endl; }
Las referencias a cout
y endl
son aquí nombres calificados. Pero si incorporamos ambos al alcance con una declaración using
, es decir, using namespace std
y solo usamos cout
solo, se convertirían en nombres no calificados
porque carecen de std::
.
Nombres dependientes y no dependientes en C++
Los nombres dependientes son los nombres que dependen de un parámetro de plantilla
.
Veamos un código de muestra para entenderlo mejor.
template <class T>
class MyClass {
int i;
vector<int> vi;
vector<int>::iterator vitr;
T t;
vector<T> vt;
vector<T>::iterator viter;
}
Las primeras tres declaraciones se conocen como nombres no dependientes porque su tipo se conoce en el momento de la declaración de la plantilla.
Mientras que si observamos el segundo conjunto de declaraciones, T
, vector<T>
y vector<T>::iterator
son nombres dependientes porque su tipo no se conoce hasta el punto de instanciación, ya que dependen de el parámetro de plantilla T
.
Uso de la palabra clave typename
en C++
Como regla general, es obligatorio usar la palabra clave typename
antes de un nombre calificado o dependiente que se refiera a un tipo.
Por lo tanto, se introduce la palabra clave typename
para especificar que el identificador que sigue es un tipo en lugar de una variable miembro estática.
class A {
public:
typedef int myPtr;
};
template <class T>
class myClass {
public:
typename T::SubType* myPtr;
}
En el código anterior, la palabra clave typename
le dice al compilador que SubType
es un tipo de clase T
, lo que significa que el puntero myptr
es un tipo de T::SubType
.
Sin la palabra clave typename
, SubType
se considerará un miembro estático, y el compilador lo evaluará como la multiplicación de SubType
de tipo T
con el puntero myptr
.
T::SubType * myptr //compiler will think it's multiplication
Si no usamos la palabra clave typename
en el código anterior, se producirá un error en tiempo de compilación porque el compilador no sabe si T::SubType
se referirá a un nombre de tipo o a un miembro estático de T
.