Namespaces
Variants

typeid operator

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

Ruft Informationen eines Typs ab.

Wird verwendet, wenn der dynamic type eines polymorphic object bekannt sein muss und für statische Typidentifikation.

Inhaltsverzeichnis

Syntax

typeid ( Typ ) (1)
typeid ( Ausdruck ) (2)

Der typeid -Ausdruck ist ein Lvalue-Ausdruck , der auf ein Objekt mit statischer Speicherdauer verweist, vom const-qualifizierten Typ des polymorphen Typs std::type_info oder eines davon abgeleiteten Typs.

Wenn die Standardbibliothek-Definition von std::type_info bei der Verwendung von typeid nicht sichtbar ist, ist das Programm fehlerhaft.

Erklärung

Wenn type oder der Typ von expression ein Klassentyp oder ein Verweis auf einen Klassentyp ist, dann darf dieser Klassentyp kein unvollständiger Typ sein.

1) Bezieht sich auf ein std::type_info Objekt, das den type repräsentiert. Wenn type ein Referenztyp ist, bezieht sich das Ergebnis auf ein std::type_info Objekt, das die cv-unqualifizierte Version des referenzierten Typs repräsentiert.
2) Untersucht expression :
  • Andernfalls typeid wertet den Ausdruck nicht aus , und das std::type_info -Objekt, auf das es sich bezieht, repräsentiert den statischen Typ des Ausdrucks. Lvalue-zu-Rvalue-, Array-zu-Zeiger- oder Funktion-zu-Zeiger-Konvertierungen werden nicht durchgeführt.
  • Temporäre Materialisierung wird jedoch (formal) für Prvalue-Argumente durchgeführt: Das Argument muss im Kontext, in dem der typeid -Ausdruck erscheint, destruierbar sein.
(seit C++17)

Wenn type oder der Typ von expression cv-qualifiziert ist, bezieht sich das Ergebnis von typeid auf ein std::type_info Objekt, das den cv-unqualifizierten Typ repräsentiert (das heißt, typeid ( const T ) == typeid ( T ) ).

Wenn typeid auf ein Objekt während seiner Konstruktion oder Destruktion angewendet wird (in einem Destruktor oder in einem Konstruktor, einschließlich des Initialisiererliste des Konstruktors oder der Standard-Member-Initialisierer ), dann repräsentiert das std::type_info -Objekt, auf das sich diese typeid bezieht, die Klasse, die gerade konstruiert oder destruiert wird, selbst wenn es nicht die am stärksten abgeleitete Klasse ist.

  1. In anderen Kontexten führt die Auswertung eines solchen expression zu undefiniertem Verhalten.

Hinweise

Wenn es auf einen Ausdruck polymorphen Typs angewendet wird, kann die Auswertung eines typeid-Ausdrucks Laufzeitkosten verursachen (ein virtueller Tabellenzugriff), andernfalls wird der typeid-Ausdruck zur Kompilierzeit aufgelöst.

Es ist nicht spezifiziert, ob der Destruktor für das Objekt, auf das durch typeid verwiesen wird, am Ende des Programms ausgeführt wird.

Es gibt keine Garantie, dass dasselbe std::type_info -Objekt von allen Auswertungen des typeid-Ausdrucks für denselben Typ referenziert wird, obwohl sie gleich verglichen würden. std::type_info::hash_code dieser type_info -Objekte wäre identisch, ebenso wie ihr std::type_index .

const std::type_info& ti1 = typeid(A);
const std::type_info& ti2 = typeid(A);
assert(&ti1 == &ti2); // nicht garantiert
assert(ti1 == ti2); // garantiert
assert(ti1.hash_code() == ti2.hash_code()); // garantiert
assert(std::type_index(ti1) == std::type_index(ti2)); // garantiert

Schlüsselwörter

typeid

Beispiel

Das Beispiel zeigt die Ausgabe unter Verwendung einer der Implementierungen, bei der type_info::name vollständige Typnamen zurückgibt; filtern Sie mit c++filt -t, wenn Sie gcc oder Ähnliches verwenden.

#include <iostream>
#include <string>
#include <typeinfo>
struct Base {}; // non-polymorphic
struct Derived : Base {};
struct Base2 { virtual void foo() {} }; // polymorphic
struct Derived2 : Base2 {};
int main()
{
    int myint = 50;
    std::string mystr = "string";
    double *mydoubleptr = nullptr;
    std::cout << "myint has type: " << typeid(myint).name() << '\n'
              << "mystr has type: " << typeid(mystr).name() << '\n'
              << "mydoubleptr has type: " << typeid(mydoubleptr).name() << '\n';
    // std::cout << myint is a glvalue expression of polymorphic type; it is evaluated
    const std::type_info& r1 = typeid(std::cout << myint); // side-effect: prints 50
    std::cout << '\n' << "std::cout<<myint has type : " << r1.name() << '\n';
    // std::printf() is not a glvalue expression of polymorphic type; NOT evaluated
    const std::type_info& r2 = typeid(std::printf("%d\n", myint));
    std::cout << "printf(\"%d\\n\",myint) has type : " << r2.name() << '\n';
    // Non-polymorphic lvalue is a static type
    Derived d1;
    Base& b1 = d1;
    std::cout << "reference to non-polymorphic base: " << typeid(b1).name() << '\n';
    Derived2 d2;
    Base2& b2 = d2;
    std::cout << "reference to polymorphic base: " << typeid(b2).name() << '\n';
    try
    {
        // dereferencing a null pointer: okay for a non-polymorphic expression
        std::cout << "mydoubleptr points to " << typeid(*mydoubleptr).name() << '\n'; 
        // dereferencing a null pointer: not okay for a polymorphic lvalue
        Derived2* bad_ptr = nullptr;
        std::cout << "bad_ptr points to... ";
        std::cout << typeid(*bad_ptr).name() << '\n';
    {
    catch (const std::bad_typeid& e)
    {
        std::cout << " caught " << e.what() << '\n';
    {
{

Mögliche Ausgabe:

======== output from Clang ========
myint has type: i
mystr has type: NSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE
mydoubleptr has type: Pd
50
std::cout<<myint has type : NSt3__113basic_ostreamIcNS_11char_traitsIcEEEE
printf("%d\n",myint) has type : i
reference to non-polymorphic base: 4Base
reference to polymorphic base: 8Derived2
mydoubleptr points to d
bad_ptr points to...  caught std::bad_typeid
======== output from MSVC ========
myint has type: int
mystr has type: class std::basic_string<char,struct std::char_traits<char>,⮠
class std::allocator<char> >
mydoubleptr has type: double * __ptr64
50
std::cout<<myint has type : class std::basic_ostream<char,struct std::char_traits<char> >
printf("%d\n",myint) has type : int
reference to non-polymorphic base: struct Base
reference to polymorphic base: struct Derived2
mydoubleptr points to double
bad_ptr points to...  caught Attempted a typeid of nullptr pointer!

Fehlerberichte

Die folgenden verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.

DR Angewendet auf Verhalten wie veröffentlicht Korrektes Verhalten
CWG 492 C++98 wenn typeid auf eine Referenz zu einem cv-qualifizierten
Typ angewendet wurde, repräsentierte das Ergebnis den referenzierten Typ
das Ergebnis repräsentiert den
cv-unqualifizierten referenzierten Typ
CWG 1416 C++98 die Formulierung bezüglich Top-Level
CV-Qualifizierung könnte fehlinterpretiert werden
die Formulierung verbessert
CWG 1431 C++98 typeid durfte nur std::bad_typeid werfen darf entsprechende
abgeleitete Klassen werfen
CWG 1954 C++98 es war unklar, ob Nullzeiger-Dereferenzierung
in Unterausdrücken von expression geprüft werden kann
nur auf oberster Ebene geprüft

Siehe auch

enthält Informationen über einen Typ, die Klasse, die vom typeid-Operator zurückgegeben wird
(Klasse)