En C ++, ¿cómo se encuentra el tipo de una variable?
En C ++, ¿cómo se encuentra el tipo de una variable?
Respuestas:
Puede usar el operador typeid :
#include <typeinfo>
...
cout << typeid(variable).name() << endl;
i
significa entero en tu compilador. Los nombres devueltos no están especificados por el estándar.
typeid
son muy abreviados, específicos del compilador y no están destinados al consumo humano. Puedes "demanglearlos" (¡ese es el término real!), Ya sea en código con algo como gcc.gnu.org/onlinedocs/libstdc++/manual/ext_demangling.html , con utilidades de línea de comandos como c++filt
, o con cualquiera de varios demandantes en línea como demangler.com .
Si tienes una variable
int k;
Puedes obtener su tipo usando
cout << typeid(k).name() << endl;
Vea el siguiente hilo en SO: Pregunta similar
La principal diferencia entre C ++ y Javascript es que C ++ es un lenguaje de tipo estático, mientras que JavaScript es dinámico.
En lenguajes de tipo dinámico, una variable puede contener cualquier cosa, y su tipo viene dado por el valor que posee, momento a momento. En lenguajes de tipo estático, el tipo de una variable se declara y no puede cambiar.
Puede haber despacho dinámico y composición y subtipo de objetos (herencia y funciones virtuales), así como despacho estático y supertipado (a través de la plantilla CRTP), pero en cualquier caso el compilador debe conocer el tipo de la variable.
Si está en posición de no saber qué es o podría ser, es porque diseñó algo ya que el lenguaje tiene un sistema de tipos dinámico.
Si ese es el caso, es mejor que reconsidere su diseño, ya que se dirige a una tierra que no es natural para el idioma que está utilizando (la mayoría es como ir en una autopista con una oruga o en el agua con un automóvil)
Por lo general, querer encontrar el tipo de una variable en C ++ es la pregunta incorrecta. Tiende a ser algo que llevas desde lenguajes de procedimiento como, por ejemplo, C o Pascal.
Si desea codificar diferentes comportamientos según el tipo, intente aprender, por ejemplo , sobrecarga de funciones y herencia de objetos . Esto no tendrá sentido inmediato en su primer día de C ++, pero continúe.
Creo que tengo un caso de uso válido para usar typeid (), de la misma manera que es válido para usar sizeof (). Para una función de plantilla, necesito poner un caso especial en el código basado en la variable de plantilla, para ofrecer la máxima funcionalidad y flexibilidad.
Es mucho más compacto y fácil de mantener que usar polimorfismo, para crear una instancia de la función para cada tipo admitido. Incluso en ese caso, podría usar este truco para escribir el cuerpo de la función solo una vez:
Tenga en cuenta que debido a que el código usa plantillas, la siguiente declaración de cambio debería resolverse estáticamente en un solo bloque de código, optimizando todos los casos falsos, AFAIK.
Considere este ejemplo, donde podemos necesitar manejar una conversión si T es un tipo versus otro. Lo uso para la especialización de clase para acceder al hardware donde el hardware usará el tipo myClassA o myClassB. En una falta de coincidencia, necesito pasar tiempo convirtiendo los datos.
switch ((typeid(T)) {
case typeid(myClassA):
// handle that case
break;
case typeid(myClassB):
// handle that case
break;
case typeid(uint32_t):
// handle that case
break;
default:
// handle that case
}
typeid
simplemente no puede ser una comprobación estática en tiempo de compilación, por definición, por lo que esto no facilita ninguna optimización. For a template function, I need to special case the code based on the template variable
Bien, entonces lo que realmente quieres es un polimorfismo estático a través del lenguaje CRTP. Esto es exactamente lo que eso logra.
No estoy seguro de si mi respuesta ayudaría.
La respuesta corta es que realmente no necesitas / quieres saber el tipo de variable para usarla.
Si necesita dar un tipo a una variable estática, entonces simplemente puede usar auto.
En el caso más sofisticado donde desee usar "auto" en una clase o estructura, sugeriría usar template con decltype.
Por ejemplo, supongamos que está utilizando la biblioteca de otra persona y tiene una variable llamada "unknown_var" y desea ponerla en un vector o estructura, puede hacer esto totalmente:
template <typename T>
struct my_struct {
int some_field;
T my_data;
};
vector<decltype(unknown_var)> complex_vector;
vector<my_struct<decltype(unknown_var)> > simple_vector
Espero que esto ayude.
EDITAR: En buena medida, este es el caso más complejo en el que puedo pensar: tener una variable global de tipo desconocido. En este caso, necesitaría c ++ 14 y plantilla variable.
Algo como esto:
template<typename T> vector<T> global_var;
void random_func (auto unknown_var) {
global_var<decltype(unknown_var)>.push_back(unknown_var);
}
Todavía es un poco tedioso, pero está lo más cerca posible de los idiomas sin tipo. Solo asegúrese de hacer referencia a la variable de plantilla, siempre coloque la especificación de plantilla allí.
Si necesita hacer una comparación entre una clase y un tipo conocido, por ejemplo:
class Example{};
...
Example eg = Example();
Puedes usar esta línea de comparación:
bool isType = string( typeid(eg).name() ).find("Example") != string::npos;
que comprueba que el typeid
nombre contiene el tipo de cadena (el nombre del tipo de letra tiene otros datos destrozados, por lo que es mejor hacer un en s1.find(s2)
lugar de ==
).
Definitivamente puede ir a typeid(x).name()
donde x es el nombre de la variable. En realidad, devuelve un puntero constante al tipo de datos. Ahora, mira el siguiente código.
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n = 36;
char c = 'A';
double d = 1.2;
if(*(typeid(n).name()) == 'i'){
cout << "I am an Integer variable" << endl;
}
if(*((char *) typeid(d).name()) == 'd'){
cout << "I am a Double variable" << endl;
}
if(*((char *) typeid(c).name()) == 'c'){
cout << "I am a Char variable" << endl;
}
return 0;
}
Observe cómo primero y segundo ambos si funciona.
std::cout << "I'm a variable of type " << typeid(n).name()
. (redactado nuevamente para evitar artefactos a / an, pero eso se puede solucionar con otra verificación). Incluso entonces, si realmente quieres una comparación, es mucho mejor hacerlotypeid(n) == typeid(int)