[expr.typeid]

# 7 Expressions [[expr]](./#expr)

## 7.6 Compound expressions [[expr.compound]](expr.compound#expr.typeid)

### 7.6.1 Postfix expressions [[expr.post]](expr.post#expr.typeid)

#### 7.6.1.8 Type identification [expr.typeid]

[1](#1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L4555)

The result of a typeid expression is an lvalue of static typeconst std​::​type_info ([[type.info]](type.info "17.7.3 Class type_­info")) and dynamic type conststd​::​type_info or const *name* where *name* is animplementation-defined class publicly derived fromstd​::​type_info which preserves the behavior described
in [[type.info]](type.info "17.7.3 Class type_­info")[.](#1.sentence-1)[52](#footnote-52 "The recommended name for such a class is extended_­type_­info.")

The lifetime of the object referred to by the lvalue extends to the end
of the program[.](#1.sentence-2)

Whether or not the destructor is called for thestd​::​type_info object at the end of the program is unspecified[.](#1.sentence-3)

[2](#2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L4574)

If the type of the [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]") or [*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]") operand is
a (possibly cv-qualified) class type or
a reference to (possibly cv-qualified) class type,
that class shall be completely defined[.](#2.sentence-1)

[3](#3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L4580)

If an [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]") operand of typeid is
a possibly-parenthesized [*unary-expression*](expr.unary.general#nt:unary-expression "7.6.2.1 General [expr.unary.general]") whose [*unary-operator*](expr.unary.general#nt:unary-operator "7.6.2.1 General [expr.unary.general]") is * and
whose operand evaluates to a null pointer value ([[basic.compound]](basic.compound "6.9.4 Compound types")),
the typeid expression throws an exception ([[except.throw]](except.throw "14.2 Throwing an exception"))
of a type that would match a handler of typestd​::​bad_typeid ([[bad.typeid]](bad.typeid "17.7.5 Class bad_­typeid"))[.](#3.sentence-1)

[*Note [1](#note-1)*:

In other contexts, evaluating such a [*unary-expression*](expr.unary.general#nt:unary-expression "7.6.2.1 General [expr.unary.general]") results in undefined behavior ([[expr.unary.op]](expr.unary.op "7.6.2.2 Unary operators"))[.](#3.sentence-2)

â *end note*]

[4](#4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L4595)

When typeid is applied to a glvalue whose type is a
polymorphic class type ([[class.virtual]](class.virtual "11.7.3 Virtual functions")), the result refers to astd​::​type_info object representing the type of the most derived
object ([[intro.object]](intro.object "6.8.2 Object model")) (that is, the dynamic type) to which the
glvalue refers[.](#4.sentence-1)

[5](#5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L4602)

When typeid is applied to an expression other than a glvalue of
a polymorphic class type, the result refers to a std​::​type_info object representing the static type of the expression[.](#5.sentence-1)

[Lvalue-to-rvalue](conv.lval "7.3.2 Lvalue-to-rvalue conversion [conv.lval]"), [array-to-pointer](conv.array "7.3.3 Array-to-pointer conversion [conv.array]"),
and [function-to-pointer](conv.func "7.3.4 Function-to-pointer conversion [conv.func]") conversions are not applied to
the expression[.](#5.sentence-2)

If the expression is a prvalue,
the [temporary materialization conversion](conv.rval "7.3.5 Temporary materialization conversion [conv.rval]") is applied[.](#5.sentence-3)

The expression is an [unevaluated operand](expr.context#def:unevaluated_operand "7.2.3 Context dependence [expr.context]")[.](#5.sentence-4)

[6](#6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L4614)

When typeid is applied to a [*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]"), the result
refers to a std​::​type_info object representing the type of the[*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]")[.](#6.sentence-1)

If the type of the [*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]") is a reference
to a possibly cv-qualified type, the result of thetypeid expression refers to a std​::​type_info object
representing the cv-unqualified referenced type[.](#6.sentence-2)

[*Note [2](#note-2)*:

The [*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]") cannot denote a function type with
a [*cv-qualifier-seq*](dcl.decl.general#nt:cv-qualifier-seq "9.3.1 General [dcl.decl.general]") or a [*ref-qualifier*](dcl.decl.general#nt:ref-qualifier "9.3.1 General [dcl.decl.general]") ([[dcl.fct]](dcl.fct "9.3.4.6 Functions"))[.](#6.sentence-3)

â *end note*]

[7](#7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L4626)

If the type of the expression or [*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]") is a
cv-qualified type, the result of the typeid expression refers
to a std​::​type_info object representing the cv-unqualified
type[.](#7.sentence-1)

[*Example [1](#example-1)*: class D { /* ... */ };
D d1;const D d2;

typeid(d1) == typeid(d2); // yields truetypeid(D) == typeid(const D); // yields truetypeid(D) == typeid(d2); // yields truetypeid(D) == typeid(const D&); // yields true â *end example*]

[8](#8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L4644)

The type std​::​type_info ([[type.info]](type.info "17.7.3 Class type_­info")) is not predefined;
if a standard library declaration ([[typeinfo.syn]](typeinfo.syn "17.7.2 Header <typeinfo> synopsis"), [[std.modules]](std.modules "16.4.2.4 Modules")) ofstd​::​type_info does not precede ([[basic.lookup.general]](basic.lookup.general "6.5.1 General"))
a typeid expression, the program is ill-formed[.](#8.sentence-1)

[9](#9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L4650)

[*Note [3](#note-3)*:

Subclause [[class.cdtor]](class.cdtor "11.9.5 Construction and destruction") describes the behavior of typeid applied to an object under construction or destruction[.](#9.sentence-1)

â *end note*]

[52)](#footnote-52)[52)](#footnoteref-52)

The recommended name for such a class isextended_type_info[.](#footnote-52.sentence-1)
