8 Expressions [expr]

8.2 Postfix expressions [expr.post]

8.2.8 Type identification [expr.typeid]

The result of a typeid expression is an lvalue of static type const std​::​type_­info ([type.info]) and dynamic type const std​::​type_­info or const name where name is an implementation-defined class publicly derived from std​::​type_­info which preserves the behavior described in [type.info].70
The lifetime of the object referred to by the lvalue extends to the end of the program.
Whether or not the destructor is called for the std​::​type_­info object at the end of the program is unspecified.
When typeid is applied to a glvalue expression whose type is a polymorphic class type ([class.virtual]), the result refers to a std​::​type_­info object representing the type of the most derived object ([intro.object]) (that is, the dynamic type) to which the glvalue refers.
If the glvalue expression is obtained by applying the unary * operator to a pointer71 and the pointer is a null pointer value ([conv.ptr]), the typeid expression throws an exception ([except.throw]) of a type that would match a handler of type std​::​bad_­typeid exception ([bad.typeid]).
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.
Lvalue-to-rvalue ([conv.lval]), array-to-pointer ([conv.array]), and function-to-pointer ([conv.func]) conversions are not applied to the expression.
If the expression is a prvalue, the temporary materialization conversion ([conv.rval]) is applied.
The expression is an unevaluated operand (Clause [expr]).
When typeid is applied to a type-id, the result refers to a std​::​type_­info object representing the type of the type-id.
If the type of the type-id is a reference to a possibly cv-qualified type, the result of the typeid expression refers to a std​::​type_­info object representing the cv-unqualified referenced type.
If the type of the type-id is a class type or a reference to a class type, the class shall be completely-defined.
If the type of the expression or type-id is a cv-qualified type, the result of the typeid expression refers to a std​::​type_­info object representing the cv-unqualified type.
[Example
:
class D { /* ... */ };
D d1;
const D d2;

typeid(d1) == typeid(d2);       // yields true
typeid(D)  == typeid(const D);  // yields true
typeid(D)  == typeid(d2);       // yields true
typeid(D)  == typeid(const D&); // yields true
end example
]
If the header <typeinfo> ([type.info]) is not included prior to a use of typeid, the program is ill-formed.
[Note
:
[class.cdtor] describes the behavior of typeid applied to an object under construction or destruction.
end note
]
The recommended name for such a class is extended_­type_­info.
If p is an expression of pointer type, then *p, (*p), *(p), ((*p)), *((p)), and so on all meet this requirement.