‘typeid’ versus ‘typeof’ in C++

Ik vraag me af wat het verschil is tussen typeiden typeofin C++. Dit is wat ik weet:

  • typeidwordt genoemd in de documentatie voor type_infodie is gedefinieerd in het C++-headerbestand typeinfo.

  • typeofwordt 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 typeidniet 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 typeofzoekwoord.

typeidis 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_infoobjecten 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 typeidnaar hetzelfde type verschillende type_infoobjecten (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%

typeidkan 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.

typeofis 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. typeofretourneert het type van een expressie, maar het is niet standaard. In C++0x is er iets genaamd decltypedat hetzelfde werk doet AFAIK.

decltype(0xdeedbeef) number = 0; // number is of type int!
decltype(someArray[0]) element = someArray[0];

Terwijl typeidwordt gebruikt met polymorfe typen. Laten we bijvoorbeeld zeggen dat catanimalafleidt:

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);

Other episodes