Me pregunto cuál es la diferencia entre typeid
y typeof
en C ++. Esto es lo que sé:
typeid
se menciona en la documentación de type_info que se define en el archivo de encabezado C ++ typeinfo .typeof
se define en la extensión GCC para C y en la biblioteca Boost de C ++ .
Además, aquí está la prueba de código de prueba que he creado donde descubrí que typeid
no devuelve lo que esperaba. ¿Por qué?
main.cpp
#include <iostream>
#include <typeinfo> //for 'typeid' to work
class Person {
public:
// ... Person members ...
virtual ~Person() {}
};
class Employee : public Person {
// ... Employee members ...
};
int main () {
Person person;
Employee employee;
Person *ptr = &employee;
int t = 3;
std::cout << typeid(t).name() << std::endl;
std::cout << typeid(person).name() << std::endl; // Person (statically known at compile-time)
std::cout << typeid(employee).name() << std::endl; // Employee (statically known at compile-time)
std::cout << typeid(ptr).name() << std::endl; // Person * (statically known at compile-time)
std::cout << typeid(*ptr).name() << std::endl; // Employee (looked up dynamically at run-time
// because it is the dereference of a pointer
// to a polymorphic class)
}
salida:
bash-3.2$ g++ -Wall main.cpp -o main
bash-3.2$ ./main
i
6Person
8Employee
P6Person
8Employee
name()
está definida por la implementación. No tiene que ser un nombre de identificador de C ++ válido, solo algo que identifique de forma exclusiva el tipo. Parece que su implementación utiliza el esquema general de cambio de nombre del compilador.Respuestas:
El lenguaje C ++ no tiene tal cosa como
typeof
. Debe estar mirando alguna extensión específica del compilador. Si está hablando de GCCtypeof
, entonces una característica similar está presente en C ++ 11 a través de la palabra clavedecltype
. De nuevo, C ++ no tiene esatypeof
palabra clave.typeid
es un operador de lenguaje C ++ que devuelve información de identificación de tipo en tiempo de ejecución. Básicamente devuelve untype_info
objeto, que es comparable a la igualdad con otrostype_info
objetos.Tenga en cuenta que la única propiedad definida del
type_info
objeto devuelto es que es comparable a la igualdad y no a la igualdad, es decir, lostype_info
objetos que describen diferentes tipos deben comparar no iguales, mientras que lostype_info
objetos que describen el mismo tipo tienen que comparar iguales. Todo lo demás está definido por la implementación. No se garantiza que los métodos que devuelven varios "nombres" devuelvan nada legible para los humanos, e incluso no se garantiza que devuelvan nada en absoluto.Tenga en cuenta también que lo anterior probablemente implica (aunque el estándar no parece mencionarlo explícitamente) que las aplicaciones consecutivas
typeid
del mismo tipo podrían devolver diferentestype_info
objetos (que, por supuesto, todavía tienen que comparar iguales).fuente
decltype
? No estoy seguro de cuál es la política general, pero como la pregunta está etiquetadaC++
, esperaría que se refiera al último estándar. Volver a etiquetar la pregunta comoC++03
también sería una opción en mi humilde opinión. Personalmente, a veces me confundo bastante, ya que tengo que usar preC ++ 11 en el trabajo y a veces no estoy seguro de lo que es verdadero "pre11" o "post11".decltype
no es un reemplazo paratypeof
.typeof
funciona en tipos también mientrasdecltype
no lo hace. Por ejemplo,typeof(int)
esint
whiledecltype(int)
es un error.type_info
objetos que describen diferentes tipos compararán no iguales" . En realidad, esto no está garantizado . El operador de desigualdad se eliminó en C ++ 20 para (supongo) desalentar la dependencia de diferentes tipos de comparación no igual. Pero si lo piensas bien, la igualdad no es segura si la desigualdad no es segura.La principal diferencia entre los dos es la siguiente
Tipo de referencia: http://www.delorie.com/gnu/docs/gcc/gcc_36.html
Referencia typeid: https://en.wikipedia.org/wiki/Typeid
fuente
typeid
puede operar en tiempo de ejecución y devolver un objeto que describe el tipo de tiempo de ejecución del objeto, que debe ser un puntero a un objeto de una clase con métodos virtuales para que RTTI (información de tipo de tiempo de ejecución) se almacene en la clase. También puede dar el tipo de tiempo de compilación de una expresión o un nombre de tipo, si no se le da un puntero a una clase con información de tipo de tiempo de ejecución.typeof
es una extensión de GNU y le da el tipo de cualquier expresión en tiempo de compilación. Esto puede ser útil, por ejemplo, para declarar variables temporales en macros que pueden usarse en múltiples tipos. En C ++, generalmente usaría plantillas en su lugar.fuente
typeid
aceptará cualquier expresión, no solo aquellas que evalúen objetos con métodos virtuales. Además,typeid
aceptará un nombre de tipo , no solo una expresión. Puedes decirtypeid(5)
otypeid(std::string)
si quieres.typeid
puede devolver información de tipo de tiempo de ejecución si está disponible, pero proporcionará información de tipo de tiempo de compilación para cualquier otra cosa.Respondiendo la pregunta adicional:
No hay nada malo. Lo que ves es la representación de cadena del nombre del tipo. El estándar C ++ no obliga a los compiladores a emitir el nombre exacto de la clase, solo depende del implementador (proveedor del compilador) decidir qué es adecuado. En resumen, los nombres dependen del compilador.
Estas son dos herramientas diferentes.
typeof
devuelve el tipo de una expresión, pero no es estándar. En C ++ 0x hay algo llamadodecltype
que hace el mismo trabajo AFAIK.Mientras que
typeid
se usa con tipos polimórficos. Por ejemplo, digamos quecat
derivaanimal
:fuente
typeid proporciona el tipo de datos en tiempo de ejecución, cuando se solicita. Typedef es una construcción en tiempo de compilación que define un nuevo tipo como se indica después de eso. No hay typeof en C ++ La salida aparece como (se muestra como comentarios inscritos):
fuente
Puede usar Boost demangle para lograr un nombre bonito:
y algo como
fuente