'Typeid' contro 'typeof' in C ++
Domanda
Mi chiedo quale sia la differenza tra il typeid
e typeof
in C ++. Ecco quello che so:
-
typeid
è menzionato nella documentazione per type_info che è definito in C ++ file di intestazione typeinfo . -
typeof
è definito nell'estensione GCC per C e in C ++ Spinta biblioteca.
Inoltre, qui è prova di codice di prova che ho creato in cui ho scoperto che typeid
non restituisce quello che mi aspettavo. Perché?
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)
}
uscita:
bash-3.2$ g++ -Wall main.cpp -o main
bash-3.2$ ./main
i
6Person
8Employee
P6Person
8Employee
Soluzione
C ++ non ha alcuna cosa come typeof
. È necessario essere guardando un po 'di estensione specifica del compilatore. Se si sta parlando di typeof
di GCC, quindi una funzione simile è presente in C ++ 11 attraverso la parola chiave decltype
. Anche in questo caso, C ++ non ha tale parola chiave typeof
.
typeid
è un C ++ operatore di lingua che restituisce tipo di informazioni di identificazione in fase di esecuzione. Restituisce fondamentalmente un oggetto type_info
, che è uguaglianza comparabile con altri oggetti type_info
.
Si noti che la proprietà unica definita dell'oggetto type_info
restituito ha è suo essere, cioè type_info
oggetti Uguaglianza e non-uguaglianza comparabile descrivono tipi diversi devono confrontare non uguali, mentre gli oggetti type_info
descrive lo stesso tipo devono confrontare pari. Tutto il resto è definito dall'implementazione. I metodi che restituiscono diversi "nomi" non sono garantiti di restituire qualcosa di leggibile, e anche se non garantito per restituire qualcosa a tutti.
Si noti inoltre, che la suddetta probabilmente implica (anche se lo standard non sembra accennare esplicitamente) che le applicazioni consecutive di typeid
allo stesso tipo potrebbero restituire diversi oggetti type_info
(che, naturalmente, devono ancora confrontare uguale) .
Altri suggerimenti
La differenza principale tra i due è il seguente
- typeof è un costrutto fase di compilazione e restituisce il tipo definito in fase di compilazione
- typeid è un costrutto runtime e quindi fornisce informazioni sul tipo di runtime valore.
typeof Riferimento: http://www.delorie.com/gnu/docs /gcc/gcc_36.html
typeid Riferimento: https://en.wikipedia.org/wiki/Typeid
typeid
può operare in fase di esecuzione, e restituire un oggetto che descrive il tipo runtime dell'oggetto , che deve essere un puntatore a un oggetto di una classe con metodi virtuali in modo per RTTI (run-time digitare le informazioni) da memorizzare nella classe. Si può anche dare il tipo tempo di compilazione di un'espressione o di un nome del tipo, se non dato un puntatore a una classe con informazioni sul tipo di esecuzione.
typeof
è un'estensione GNU, e ti dà il tipo di qualsiasi espressione al momento della compilazione. Questo può essere utile, per esempio, nel dichiarare variabili temporanee nelle macro che possono essere utilizzati su più tipi. In C ++, che di solito utilizzare modelli .
Rispondendo alla domanda aggiuntiva:
il mio seguente codice di prova per typeid fa Non uscita il nome del tipo corretto. cosa c'è di sbagliato?
Non c'è niente di male. Quello che si vede è la rappresentazione di stringa del nome del tipo. Il C ++ standard non forzare compilatori per emettere il nome esatto della classe, è solo fino al realizzatore (produttore del compilatore) per decidere che cosa è adatto. In breve, i nomi sono fino al compilatore.
Si tratta di due strumenti diversi. typeof
restituisce il tipo di espressione, ma non è standard. In C ++ 0x c'è una cosa chiamata decltype
che fa lo stesso lavoro per quanto ne so.
decltype(0xdeedbeef) number = 0; // number is of type int!
decltype(someArray[0]) element = someArray[0];
considerando che typeid
viene utilizzato con i tipi polimorfici. Ad esempio, consente di dire che cat
deriva 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 fornisce il tipo di dati in fase di runtime, quando abbiamo chiesto. Typedef è un costrutto di compilazione che definisce un nuovo tipo indicato dopo. Non v'è alcun typeof in C ++ Uscita appare come (indicato come commenti iscritti):
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
È possibile utilizzare Boost demangle per realizzare un bel nome alla ricerca:
#include <boost/units/detail/utility.hpp>
e qualcosa come
To_main_msg_evt ev("Failed to initialize cards in " + boost::units::detail::demangle(typeid(*_IO_card.get()).name()) + ".\n", true, this);