Ik vraag me af wat het verschil is tussen typeid
en typeof
in C++. Dit is wat ik weet:
-
typeid
wordt genoemd in de documentatie voor type_infodie is gedefinieerd in het C++-headerbestand typeinfo. -
typeof
wordt gedefinieerd in de GCC-extensie voor C en in de C++ Boostbibliotheek.
Hier is ook een testcodetest die ik heb gemaakt, waarbij ik heb ontdekt dat typeid
niet oplevert wat ik had verwacht. Waarom?
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)
}
uitvoer:
bash-3.2$ g++ -Wall main.cpp -o main
bash-3.2$ ./main
i
6Person
8Employee
P6Person
8Employee
Antwoord 1, autoriteit 100%
C++-taal heeft niet zoiets als typeof
. Je moet kijken naar een compiler-specifieke extensie. Als je het hebt over GCC’s typeof
, dan is een vergelijkbare functie aanwezig in C++11 via het trefwoord decltype
. Nogmaals, C++ heeft niet zo’n typeof
zoekwoord.
typeid
is een C++-taaloperator die tijdens runtime type-identificatie-informatie retourneert. Het retourneert in feite een type_info
-object, dat vergelijkbaar is met andere type_info
-objecten.
Merk op dat de enige gedefinieerde eigenschap van het geretourneerde type_info
-object is dat het gelijkheids- en niet-gelijkheidsvergelijkbaar is, dwz type_info
-objecten die verschillende typen beschrijven, moeten worden vergeleken ongelijk, terwijl type_info
objecten die hetzelfde type beschrijven gelijk moeten worden vergeleken. Al het andere is implementatie-gedefinieerd. Methoden die verschillende “namen” retourneren, zullen niet gegarandeerd iets voor mensen leesbaar retourneren, en zelfs helemaal niet gegarandeerd.
Merk ook op dat het bovenstaande waarschijnlijk impliceert (hoewel de standaard dit niet expliciet lijkt te vermelden) dat opeenvolgende toepassingen van typeid
naar hetzelfde type verschillende type_info
objecten (die natuurlijk nog steeds gelijk moeten worden vergeleken).
Antwoord 2, autoriteit 24%
Het belangrijkste verschil tussen de twee is het volgende
- typeof is een constructie tijdens het compileren en geeft het type terug zoals gedefinieerd tijdens het compileren
- typeid is een runtime-constructie en geeft daarom informatie over het runtime-type van de waarde.
typereferentie: http://www.delorie.com/gnu/docs /gcc/gcc_36.html
typeid-referentie: https://en.wikipedia.org/wiki/Typeid
Antwoord 3, autoriteit 12%
typeid
kan tijdens runtime werken en een object retourneren dat beschrijft het runtime-type van het object, dat een verwijzing moet zijn naar een object van een klasse met virtuele methoden om RTTI (run-time type informatie)om in de klas op te slaan. Het kan ook het compileertijdtype van een expressie of een typenaam geven, als het geen verwijzing naar een klasse met runtime-type-informatie geeft.
typeof
is een GNU-extensie en geeft u het type van elke expressie tijdens het compileren. Dit kan bijvoorbeeld handig zijn bij het declareren van tijdelijke variabelen in macro’s die op meerdere typen kunnen worden gebruikt. In C++ zou je in plaats daarvan meestal sjablonengebruiken.
Antwoord 4, autoriteit 11%
De aanvullende vraag beantwoorden:
mijn volgende testcode voor typeid wel
niet de juiste typenaam uitvoeren.
wat is er aan de hand?
Er is niets mis. Wat u ziet, is de tekenreeksrepresentatie van de typenaam. De standaard C++ dwingt compilers niet om de exacte naam van de klasse uit te zenden, het is gewoon aan de uitvoerder (verkoper van de compiler) om te beslissen wat geschikt is. Kortom, de namen zijn aan de compiler.
Dit zijn twee verschillende tools. typeof
retourneert het type van een expressie, maar het is niet standaard. In C++0x is er iets genaamd decltype
dat hetzelfde werk doet AFAIK.
decltype(0xdeedbeef) number = 0; // number is of type int!
decltype(someArray[0]) element = someArray[0];
Terwijl typeid
wordt gebruikt met polymorfe typen. Laten we bijvoorbeeld zeggen dat cat
animal
afleidt:
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.
}
Antwoord 5, autoriteit 2%
typeid geeft het type gegevens tijdens runtime, wanneer daarom wordt gevraagd. Typedef is een constructie voor compileren die een nieuw type definieert zoals daarna vermeld. Er is geen typeof in C++
Uitvoer verschijnt als (weergegeven als ingeschreven opmerkingen):
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
Antwoord 6
Je kunt Boost demangle gebruiken om een mooie naam te krijgen:
#include <boost/units/detail/utility.hpp>
en zoiets
To_main_msg_evt ev("Failed to initialize cards in " + boost::units::detail::demangle(typeid(*_IO_card.get()).name()) + ".\n", true, this);