[support.rtti]

# 17 Language support library [[support]](./#support)

## 17.7 Type identification [support.rtti]

### [17.7.1](#general) General [[support.rtti.general]](support.rtti.general)

[1](#general-1)

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

The header [<typeinfo>](#header:%3ctypeinfo%3e "17.7.2 Header <typeinfo> synopsis [typeinfo.syn]") defines a
type associated with type information generated by the implementation[.](#general-1.sentence-1)

It also defines two types for reporting dynamic type identification errors[.](#general-1.sentence-2)

The header [<typeindex>](#header:%3ctypeindex%3e "17.7.6 Header <typeindex> synopsis [type.index.synopsis]") defines
a wrapper type for use as an index type in associative containers ([[associative]](associative "23.4 Associative containers"))
and in unordered associative containers ([[unord]](unord "23.5 Unordered associative containers"))[.](#general-1.sentence-3)

### [17.7.2](#typeinfo.syn) Header <typeinfo> synopsis [[typeinfo.syn]](typeinfo.syn)

[ð](#header:%3ctypeinfo%3e)

// all freestandingnamespace std {class type_info; class bad_cast; class bad_typeid;}

### [17.7.3](#type.info) Class type_info [[type.info]](type.info)

[ð](#lib:type_info_)

namespace std {class type_info {public:virtual ~type_info(); constexpr bool operator==(const type_info& rhs) const noexcept; bool before(const type_info& rhs) const noexcept;
 size_t hash_code() const noexcept; const char* name() const noexcept;

 type_info(const type_info&) = delete;
 type_info& operator=(const type_info&) = delete; };}

[1](#type.info-1)

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

The classtype_info describes type information generated by the implementation ([[expr.typeid]](expr.typeid "7.6.1.8 Type identification"))[.](#type.info-1.sentence-1)

Objects of this class effectively store a pointer to a name for the type, and
an encoded value suitable for comparing two types for equality or collating order[.](#type.info-1.sentence-2)

The names, encoding rule, and collating sequence for types are all unspecifiedand may differ between programs[.](#type.info-1.sentence-3)

[ð](#lib:operator==,type_info)

`constexpr bool operator==(const type_info& rhs) const noexcept;
`

[2](#type.info-2)

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

*Effects*: Compares the current object with rhs[.](#type.info-2.sentence-1)

[3](#type.info-3)

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

*Returns*: true if the two values describe the same type[.](#type.info-3.sentence-1)

[ð](#lib:before,type_info)

`bool before(const type_info& rhs) const noexcept;
`

[4](#type.info-4)

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

*Effects*: Compares the current object with rhs[.](#type.info-4.sentence-1)

[5](#type.info-5)

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

*Returns*: true if*this precedes rhs in the implementation's collation order[.](#type.info-5.sentence-1)

[ð](#lib:hash_code,type_info)

`size_t hash_code() const noexcept;
`

[6](#type.info-6)

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

*Returns*: An unspecified value, except that within a single execution of the
program, it shall return the same value for any two type_info objects which compare equal[.](#type.info-6.sentence-1)

[7](#type.info-7)

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

*Remarks*: An implementation should return different values for twotype_info objects which do not compare equal[.](#type.info-7.sentence-1)

[ð](#lib:name,type_info)

`const char* name() const noexcept;
`

[8](#type.info-8)

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

*Returns*: An implementation-defined ntbs[.](#type.info-8.sentence-1)

[9](#type.info-9)

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

*Remarks*: The message may be a[null-terminated multibyte string](multibyte.strings#def:ntmbs "16.3.3.3.4.3 Multibyte strings [multibyte.strings]"),
suitable for conversion and display as awstring ([[string.classes]](string.classes "27.4 String classes"), [[locale.codecvt]](locale.codecvt "28.3.4.2.5 Class template codecvt"))[.](#type.info-9.sentence-1)

### [17.7.4](#bad.cast) Class bad_cast [[bad.cast]](bad.cast)

[ð](#lib:bad_cast_)

namespace std {class bad_cast : public exception {public:// see [[exception]](exception "17.9.3 Class exception") for the specification of the special member functionsconstexpr const char* what() const noexcept override; };}

[1](#bad.cast-1)

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

The classbad_cast defines the type of objects thrown
as exceptions by the implementation to report the execution of an invaliddynamic_cast expression ([[expr.dynamic.cast]](expr.dynamic.cast "7.6.1.7 Dynamic cast"))[.](#bad.cast-1.sentence-1)

[ð](#lib:what,bad_cast)

`constexpr const char* what() const noexcept override;
`

[2](#bad.cast-2)

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

*Returns*: An implementation-defined ntbs[.](#bad.cast-2.sentence-1)

### [17.7.5](#bad.typeid) Class bad_typeid [[bad.typeid]](bad.typeid)

[ð](#lib:bad_typeid_)

namespace std {class bad_typeid : public exception {public:// see [[exception]](exception "17.9.3 Class exception") for the specification of the special member functionsconstexpr const char* what() const noexcept override; };}

[1](#bad.typeid-1)

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

The classbad_typeid defines the type of objects
thrown as exceptions by the implementation to report a null pointer
in atypeid expression ([[expr.typeid]](expr.typeid "7.6.1.8 Type identification"))[.](#bad.typeid-1.sentence-1)

[ð](#lib:what,bad_typeid)

`constexpr const char* what() const noexcept override;
`

[2](#bad.typeid-2)

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

*Returns*: An implementation-defined ntbs[.](#bad.typeid-2.sentence-1)

### [17.7.6](#type.index.synopsis) Header <typeindex> synopsis [[type.index.synopsis]](type.index.synopsis)

[ð](#header:%3ctypeindex%3e)

#include <compare> // see [[compare.syn]](compare.syn "17.12.1 Header <compare> synopsis")namespace std {class type_index; template<class T> struct hash; template<> struct hash<type_index>;}

### [17.7.7](#type.index) Class type_index [[type.index]](type.index)

[ð](#lib:type_index)

namespace std {class type_index {public: type_index(const type_info& rhs) noexcept; bool operator==(const type_index& rhs) const noexcept; bool operator< (const type_index& rhs) const noexcept; bool operator> (const type_index& rhs) const noexcept; bool operator<=(const type_index& rhs) const noexcept; bool operator>=(const type_index& rhs) const noexcept;
 strong_ordering operator<=>(const type_index& rhs) const noexcept;
 size_t hash_code() const noexcept; const char* name() const noexcept; private:const type_info* target; // *exposition only*// Note that the use of a pointer here, rather than a reference,// means that the default copy/move constructor and assignment// operators will be provided and work as expected.};}

[1](#type.index-1)

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

The class type_index provides a simple wrapper fortype_info which can be used as an index type in associative
containers ([[associative]](associative "23.4 Associative containers")) and in unordered associative
containers ([[unord]](unord "23.5 Unordered associative containers"))[.](#type.index-1.sentence-1)

[ð](#lib:type_index,constructor)

`type_index(const type_info& rhs) noexcept;
`

[2](#type.index-2)

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

*Effects*: Constructs a type_index object, the equivalent of target = &rhs[.](#type.index-2.sentence-1)

[ð](#lib:operator==,type_index)

`bool operator==(const type_index& rhs) const noexcept;
`

[3](#type.index-3)

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

*Returns*: *target == *rhs.target[.](#type.index-3.sentence-1)

[ð](#lib:operator%3c,type_index)

`bool operator<(const type_index& rhs) const noexcept;
`

[4](#type.index-4)

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

*Returns*: target->before(*rhs.target)[.](#type.index-4.sentence-1)

[ð](#lib:operator%3e,type_index)

`bool operator>(const type_index& rhs) const noexcept;
`

[5](#type.index-5)

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

*Returns*: rhs.target->before(*target)[.](#type.index-5.sentence-1)

[ð](#lib:operator%3c=,type_index)

`bool operator<=(const type_index& rhs) const noexcept;
`

[6](#type.index-6)

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

*Returns*: !rhs.target->before(*target)[.](#type.index-6.sentence-1)

[ð](#lib:operator%3e=,type_index)

`bool operator>=(const type_index& rhs) const noexcept;
`

[7](#type.index-7)

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

*Returns*: !target->before(*rhs.target)[.](#type.index-7.sentence-1)

[ð](#lib:operator%3c=%3e,type_index)

`strong_ordering operator<=>(const type_index& rhs) const noexcept;
`

[8](#type.index-8)

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

*Effects*: Equivalent to:if (*target == *rhs.target) return strong_ordering::equal;if (target->before(*rhs.target)) return strong_ordering::less;return strong_ordering::greater;

[ð](#lib:hash_code,type_index)

`size_t hash_code() const noexcept;
`

[9](#type.index-9)

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

*Returns*: target->hash_code()[.](#type.index-9.sentence-1)

[ð](#lib:name,type_index)

`const char* name() const noexcept;
`

[10](#type.index-10)

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

*Returns*: target->name()[.](#type.index-10.sentence-1)

[ð](#lib:hash,type_index)

`template<> struct hash<type_index>;
`

[11](#type.index-11)

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

For an object index of type type_index,hash<type_index>()(index) shall evaluate to the same result as index.hash_code()[.](#type.index-11.sentence-1)
