type_info是保有一个类型的实现指定信息的类,这里的类型不仅包括类,结构体,数值类型比如,int,double,还包括对象,指针。通过typeid运算符返回的类,可以获取该类型的指定信息包括类型的名称和比较二个类型相等的方法或相对顺序,hash_code等。
| [虚] | 虚析构函数使 type_info 为多态类(虚公开成员函数) |
| (C++20 中移除) | 检查对象是否指代相同类型 (公开成员函数) |
检查在实现定义的顺序中,被指代类型是否在另一个 type_info 对象之前,即对被指代类型排序(公开成员函数) | |
| (C++11) | 返回对于同一类型相同的值 (公开成员函数) |
| 类型的实现定义名称 (公开成员函数) |
下面是具体的示例
- #include
- #include
- #include
- #include
-
- using namespace std;
-
- class Person {
- public:
- Person(string name):
- m_name(std::move(name))
- {
-
- }
-
- virtual const string& name() const
- {
- return m_name;
- }
-
- private:
- string m_name;
- };
-
- class Employee: public Person {
- public:
- Employee(string name, string per):
- Person(std::move(name)),
- m_profession(std::move(per))
- {
-
- }
-
- const string &profession() const
- {
- return m_profession;
- }
-
- private:
- string m_profession;
- };
-
- void somefunc(const Person& per)
- {
- if(typeid(Person) == typeid(per))
- {
- cout << per.name() << " is not an employee \n";
- }
- else if(typeid (Employee) == typeid(per))
- {
- cout << per.name() << " is an Employee ";
- auto &emp = dynamic_cast<const Employee&>(per);
- cout << "who works in " << emp.profession() << "\n";
- }
- }
-
- //结构体
- struct SBase {
- public:
- virtual ~SBase() = default;
- };
-
- struct SDerived: SBase {
-
- };
-
- //类
- class CBase {
- public:
- virtual ~CBase() = default;
- };
-
- class CDerived: public CBase {
-
- };
-
- int main()
- {
- //1.1获取对象的类型信息
- SBase sbase;
- SDerived sderived;
- const SBase *pb = &sbase;
- cout << "sbase=== name = " << typeid(sbase).name() << " raw_name = " << typeid(sbase).raw_name() << " hash_code = " << typeid(sbase).hash_code() << endl;
- cout << "pb=== name = " << typeid(pb).name() << " raw_name = " << typeid(pb).raw_name() << " hash_code = " << typeid(pb).hash_code() << endl;
- cout << "*pb=== name = " << typeid(*pb).name() << " raw_name = " << typeid(*pb).raw_name() << " hash_code = " << typeid(*pb).hash_code() << endl;
- pb = &sderived;
- cout << "*pb=== name = " << typeid(*pb).name() << " raw_name = " << typeid(*pb).raw_name() << " hash_code = " << typeid(*pb).hash_code() << endl;
-
- CBase cbase;
- CDerived cderived;
- const CBase *pbc = &cbase;
- cout << "*pbc=== name = " << typeid(*pbc).name() << " raw_name = " << typeid(*pbc).raw_name() << " hash_code = " << typeid(*pbc).hash_code() << endl;
- pbc = &cderived;
- cout << "*pbc== name = " << typeid(*pbc).name() << " raw_name = " << typeid(*pbc).raw_name() << " hash_code = " << typeid(*pbc).hash_code() << endl;
-
- //1.2 获取普通变量的类型信息
- int n = 30;
- const type_info &info = typeid(n);
- cout << "int=== name = " << info.name() << " raw_name = " << info.raw_name() << " hash_code = " << info.hash_code() << endl;
-
- //1.3 获取一个字面量的类型信息
- const type_info &literalInfo = typeid(19.6);
- cout << "19.6== name = " << literalInfo.name() << " raw_name = " << literalInfo.raw_name() << " hash_code = " << literalInfo.hash_code() << endl;
-
- //1.4 获取表达式的类型信息
- const type_info &expressionInfo = typeid(50 / 2 * 3.6);
- cout << "expression name = " << expressionInfo.name() << " raw_name = " << expressionInfo.raw_name() << " hash_code = " << expressionInfo.hash_code() << endl;
- //1.5 获取结构体的类型信息
- const type_info &sinfo = typeid(SBase);
- cout << "SBase name = " << sinfo.name() << " raw_name = " << sinfo.raw_name() << " hash_code = " << sinfo.hash_code() << endl;
- //1.6 获取类的类型信息
- const type_info &cinfo = typeid(CBase);
- cout << "CBase name = " << cinfo.name() << " raw_name = " << cinfo.raw_name() << " hash_code = " << cinfo.hash_code() << endl;
-
- //2. operator==的使用
- somefunc(Employee{"Scott", "Camel"});
- somefunc(Person{"Yak"});
-
- //3. operator!=的使用
- if (typeid(Employee) != typeid(Person))
- {
- cout << "class 'Employee' != class 'Person' \n";
- }
-
- cout << endl;
- //4.before
- if(typeid(char).before(typeid(bool)))
- std::cout << "char goes before bool in this implementation.\n";
- else
- std::cout << "bool goes before char in this implementation.\n";
-
- if(typeid(char).before(typeid(short)))
- std::cout << "char goes before short in this implementation.\n";
- else
- std::cout << "short goes before char in this implementation.\n";
-
-
- if(typeid(int).before(typeid(char)))
- std::cout << "int goes before char in this implementation.\n";
- else
- std::cout << "char goes before int in this implementation.\n";
-
-
- cout << "Hello World!" << endl;
- return 0;
- }
运行结果:

接下来看一下hash_code()函数的使用:
- #include
- #include
- #include
- #include
- #include
- #include
-
- using namespace std;
-
- struct A {
- virtual ~A() {}
- };
-
- struct B : A {};
- struct C : A {};
-
- using TypeInfoRef = std::reference_wrapper<const std::type_info>;
-
- struct Hasher {
- std::size_t operator()(TypeInfoRef code) const
- {
- return code.get().hash_code();
- }
- };
-
- struct EqualTo {
- bool operator()(TypeInfoRef lhs, TypeInfoRef rhs) const
- {
- return lhs.get() == rhs.get();
- }
- };
-
- int main()
- {
- std::unordered_map
type_names; -
- type_names[typeid(int)] = "int";
- type_names[typeid(double)] = "double";
- type_names[typeid(A)] = "A";
- type_names[typeid(B)] = "B";
- type_names[typeid(C)] = "C";
-
- int i;
- double d;
- A a;
-
- // note that we're storing pointer to type A
- std::unique_ptr b(new B);
- std::unique_ptr c(new C);
-
- std::cout << "i is " << type_names[typeid(i)] << '\n';
- std::cout << "d is " << type_names[typeid(d)] << '\n';
- std::cout << "a is " << type_names[typeid(a)] << '\n';
- std::cout << "b is " << type_names[typeid(*b)] << '\n';
- std::cout << "c is " << type_names[typeid(*c)] << '\n';
- cout << "Hello World!" << endl;
- return 0;
- }
运行结果:

参考: