'Typeid' frente a 'typeof' en C ++
Pregunta
Me gustaría saber 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 cabecera C ++ typeinfo . -
typeof
se define en la extensión GCC para C y en el C ++ Boost biblioteca.
Además, es la prueba del código de prueba que he creado, donde he descubierto 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
Solución
lenguaje C ++ no tiene tal cosa como typeof
. Usted debe estar buscando en alguna extensión compilador específico. Si usted está hablando de typeof
de GCC, a continuación, una característica similar está presente en C ++ 11 a través del decltype
palabra clave. Una vez más, C ++ no tiene tal palabra clave typeof
.
typeid
es un operador de lenguaje C ++ que devuelve información de identificación de tipo en tiempo de ejecución. Básicamente devuelve un objeto type_info
, que es la igualdad-comparable con otros objetos type_info
.
Nota, que la propiedad única definida del objeto type_info
devuelto tiene es su ser igualdad- y no igualdad-comparable, es decir, type_info
objetos que describe diferentes tipos deberá comparar no igual, mientras que type_info
objetos que describe el mismo tipo tiene que comparar igual. Todo lo demás es definido por la implementación. Métodos que devuelven varios "nombres" no se garantiza que devuelve nada legible, e incluso no se garantiza que nada de retorno en absoluto.
Tenga en cuenta también, que lo anterior implica probablemente (aunque no parece el estándar mencionar explícitamente) que las aplicaciones consecutivas de typeid
al mismo tipo pueden devolver diferentes objetos type_info
(que, por supuesto, todavía tiene que comparar la igualdad) .
Otros consejos
La principal diferencia entre los dos es el siguiente
- typeof es un constructo tiempo de compilación y devuelve el tipo como se define en tiempo de compilación
- typeid es un constructo de tiempo de ejecución y por lo tanto da información sobre el tipo de tiempo de ejecución del valor.
typeof Referencia: http://www.delorie.com/gnu/docs /gcc/gcc_36.html
typeid Referencia: https://en.wikipedia.org/wiki/Typeid
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 en orden para RTTI (en tiempo de ejecución información de tipo) para ser almacenados en la clase. También se puede dar el tipo de tiempo de compilación de una expresión o un nombre de tipo, si no se da un puntero a una clase con información de tipo en 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, en la declaración de variables temporales en las macros que se pueden utilizar en múltiples tipos. En C ++, por lo general, se utilizaría plantillas lugar.
Respondiendo a la pregunta adicional:
mi siguiente código de prueba para typeid hace no se emiten el nombre del tipo correcto. lo que está mal?
No hay nada malo. Lo que se ve es la representación de cadena del nombre del tipo. El estándar de C ++ no obliga a los compiladores para emitir el nombre exacto de la clase, es sólo hasta el implementador (proveedor del compilador) para decidir lo que es adecuado. En pocas palabras, los nombres son de hasta el compilador.
Estos son dos herramientas diferentes. typeof
devuelve el tipo de una expresión, pero no es estándar. En C ++ 0x hay algo llamado decltype
la que hace el mismo trabajo que yo sepa.
decltype(0xdeedbeef) number = 0; // number is of type int!
decltype(someArray[0]) element = someArray[0];
Considerando que typeid
se utiliza con los tipos polimórficos. Por ejemplo, digamos que se basa este cat
animal
:
animal* a = new cat; // animal has to have at least one virtual function
...
if( typeid(*a) == typeid(cat) )
{
// the object is of type cat! but the pointer is base pointer.
}
typeid proporciona el tipo de los datos en tiempo de ejecución, cuando se le pide. Typedef es un constructo tiempo de compilación que define un nuevo tipo como se indica después de eso. No hay ninguna typeof en C ++ aparece como salida (que se muestra como comentarios inscritas):
std::cout << typeid(t).name() << std::endl; // i
std::cout << typeid(person).name() << std::endl; // 6Person
std::cout << typeid(employee).name() << std::endl; // 8Employee
std::cout << typeid(ptr).name() << std::endl; // P6Person
std::cout << typeid(*ptr).name() << std::endl; //8Employee
Se puede utilizar demangle Boost para lograr un buen nombre busca:
#include <boost/units/detail/utility.hpp>
y algo así como
To_main_msg_evt ev("Failed to initialize cards in " + boost::units::detail::demangle(typeid(*_IO_card.get()).name()) + ".\n", true, this);