Zastanawiam się, jaka jest różnica między typeid
iw typeof
C ++. Oto co wiem:
typeid
jest wspomniana w dokumentacji dla type_info, która jest zdefiniowana w pliku nagłówkowym C ++ typeinfo .typeof
jest zdefiniowany w rozszerzeniu GCC dla języka C oraz w bibliotece C ++ Boost .
Tutaj jest również test kodu testowego, który stworzyłem, w którym odkryłem, że typeid
nie zwraca tego, czego się spodziewałem. Czemu?
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)
}
wynik:
bash-3.2$ g++ -Wall main.cpp -o main
bash-3.2$ ./main
i
6Person
8Employee
P6Person
8Employee
name()
jest zdefiniowany przez implementację. Nie musi to być poprawna nazwa identyfikatora C ++, po prostu coś , co jednoznacznie identyfikuje typ. Wygląda na to, że Twoja implementacja używa ogólnego schematu zmiany nazw kompilatora.Odpowiedzi:
Język C ++ nie ma czegoś takiego jak
typeof
. Musisz patrzeć na jakieś rozszerzenie specyficzne dla kompilatora. Jeśli mówisz o GCCtypeof
, to podobna funkcja jest obecna w C ++ 11 poprzez słowo kluczowedecltype
. Ponownie, C ++ nie ma takiegotypeof
słowa kluczowego.typeid
jest operatorem języka C ++, który zwraca informacje identyfikujące typ w czasie wykonywania. W zasadzie zwracatype_info
obiekt, który jest porównywalny pod względem równości z innymitype_info
obiektami.Zauważ, że jedyną zdefiniowaną właściwością zwracanego
type_info
obiektu jest to, że jest on porównywalny z równością i nierównością, tj.type_info
Obiekty opisujące różne typy powinny porównywać różne typy, atype_info
obiekty opisujące ten sam typ muszą porównywać równe. Wszystko inne jest zdefiniowane w ramach implementacji. Metody, które zwracają różne „nazwy” nie gwarantują zwrócenia niczego czytelnego dla człowieka, a nawet nie gwarantują, że w ogóle zwrócą cokolwiek.Zauważ również, że powyższe prawdopodobnie implikuje (chociaż norma nie wydaje się o tym wyraźnie mówić), że kolejne aplikacje
typeid
tego samego typu mogą zwracać różnetype_info
obiekty (które oczywiście nadal muszą porównywać równe).źródło
decltype
? Nie jestem pewien, jakie są ogólne zasady, ale ponieważ pytanie zostało otagowaneC++
, spodziewam się, że będzie odnosić się do najnowszego standardu. Ponowne oznaczenie pytania jakoC++03
opcja imho. Osobiście czasami jestem trochę zdezorientowany, ponieważ muszę używać preC ++ 11 w pracy, a czasami nie jestem pewien, co jest prawdą „pre11” lub „post11”.decltype
nie zastępujetypeof
.typeof
działa również na typach, adecltype
nie. Na przykładtypeof(int)
toint
whiledecltype(int)
jest błędem.type_info
obiekty opisujące różne typy porównują nierówności” . Właściwie to nie jest gwarantowane . Operator nierówności został usunięty w C ++ 20, aby (zakładam) zniechęcić do polegania na różnych typach porównujących nierówności. Ale jeśli się nad tym zastanowić, równość nie jest bezpieczna, jeśli nierówność nie jest bezpieczna.Podstawowa różnica między nimi jest następująca
odniesienie do typu: http://www.delorie.com/gnu/docs/gcc/gcc_36.html
typeid referencyjny: https://en.wikipedia.org/wiki/Typeid
źródło
typeid
może działać w czasie wykonywania i zwracać obiekt opisujący typ obiektu w czasie wykonywania, który musi być wskaźnikiem do obiektu klasy z metodami wirtualnymi, aby RTTI (informacje o typie czasu wykonywania) mogły być przechowywane w klasie. Może również podać typ czasu kompilacji wyrażenia lub nazwę typu, jeśli nie zostanie podany wskaźnik do klasy z informacją o typie czasu wykonywania.typeof
jest rozszerzeniem GNU i podaje typ dowolnego wyrażenia w czasie kompilacji. Może to być przydatne na przykład przy deklarowaniu zmiennych tymczasowych w makrach, które mogą być używane w wielu typach. W C ++ zamiast tego używałbyś szablonów .źródło
typeid
zaakceptuje każde wyrażenie, nie tylko te, które oceniają obiekty metodami wirtualnymi. Ponadtotypeid
zaakceptuje nazwę typu , a nie tylko wyrażenie. Możesz powiedziećtypeid(5)
lubtypeid(std::string)
jeśli chcesz.typeid
może zwrócić informacje o typie czasu wykonywania, jeśli są dostępne, ale dostarczy informacje o typie czasu kompilacji dla cokolwiek innego.Odpowiadając na dodatkowe pytanie:
Nie ma nic złego. To, co widzisz, jest ciągiem reprezentującym nazwę typu. Standardowy C ++ nie wymusza na kompilatorach emisji dokładnej nazwy klasy, tylko implementator (dostawca kompilatora) decyduje, co jest odpowiednie. Krótko mówiąc, nazwy zależą od kompilatora.
To są dwa różne narzędzia.
typeof
zwraca typ wyrażenia, ale nie jest to standardowe. W C ++ 0x jest coś, co nazywadecltype
się AFAIK.Natomiast
typeid
jest używany z typami polimorficznymi. Na przykład, powiedzmy, żecat
wyprowadzaanimal
:źródło
typeid zapewnia typ danych w czasie wykonywania, gdy zostaniesz o to poproszony. Typedef to konstrukcja czasu kompilacji, która definiuje nowy typ, jak podano później. Nie ma typeof w C ++ Wyjście pojawia się jako (pokazane jako wpisane komentarze):
źródło
Możesz użyć demangle Boost, aby uzyskać ładnie wyglądającą nazwę:
i coś takiego
źródło