在 C++ 中使用 typeid 运算符
本文解释并演示了如何在 C++ 中使用 typeid
运算符。
使用 typeid
运算符在 C++ 中检索对象的类型名称
你可以使用 typeid
运算符来检索给定表达式或对象的类型信息。它返回对 std::type_info
标准库类型的引用,该类型在 <typeinfo>
标头中定义。
std::type_info
对象具有成员函数 name
,你可以利用它返回描述参数对象基础类型的字符串。请注意,由 typeid
检索的类型信息取决于实现。即,最常见的编译器 gcc
和 clang
返回经过修改的名称,如下一个代码示例所示。
Microsoft Visual C++ 等其他实现以更易读的形式显示信息。尽管如此,请记住,你仍然可以学习识别由前一个实现显示的内置类型的名称。例如,int
对象返回一个 i
字符,而指向 int
对象的指针返回一个 Pi
字符串。
#include <iostream>
#include <string>
#include <typeinfo>
using std::cout; using std::endl;
using std::string; using std::cin;
int main() {
int i1 = 1234;
string str1("arbitrary string");
auto ptr = &i1;
cout << "i1 type: " << typeid(i1).name() << '\n'
<< "str1 type: " << typeid(str1).name() << '\n'
<< "ptr type: " << typeid(ptr).name() << endl;
const std::type_info& r1 = typeid(i1);
cout << '\n' << "i1 type: " << r1.name() << '\n';
return EXIT_SUCCESS;
}
输出:
i1 type: i
str1 type: NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
ptr type: Pi
i1 type: i
另一方面,如果我们对对象的引用调用 typeid
命令,我们会发现检索到的类型信息并不总是准确的,有时太神秘而无法阅读。以下示例显示了第二次调用 typeid
运算符返回错误类型信息的情况。
#include <iostream>
#include <string>
#include <typeinfo>
using std::cout; using std::endl;
struct Base {};
struct Derived : Base {};
struct Base2 { virtual void foo() {} };
struct Derived2 : Base2 {};
int main() {
Derived d1;
Base& b1 = d1;
cout << "non-polymorphic base: " << typeid(b1).name() << '\n';
Derived2 d2;
Base2& b2 = d2;
cout << "polymorphic base: " << typeid(b2).name() << '\n';
return EXIT_SUCCESS;
}
输出:
non-polymorphic base: 4Base
polymorphic base: 8Derived2
可以使用 Boost TypeIndex 库函数 type_id_with_cvr
更正此行为,该函数可以准确返回类型信息。通常,当使用 typeid
操作符时,带有 const
、volatile
、&
和 &&
修饰符的对象都会导致错误的类型信息;因此,你应该更好地依赖 type_id_with_cvr
函数。
以下代码示例需要在系统上安装 Boost 库,并且 type_id_with_cvr
函数位于 boost::typeindex
命名空间下。
#include <iostream>
#include <string>
#include <typeinfo>
#include <boost/type_index.hpp>
using std::cout; using std::endl;
using boost::typeindex::type_id_with_cvr;
struct Base {};
struct Derived : Base {};
struct Base2 { virtual void foo() {} };
struct Derived2 : Base2 {};
int main() {
Derived d1;
Base& b1 = d1;
Derived2 d2;
Base2& b2 = d2;
cout << type_id_with_cvr<decltype(b1)>().pretty_name() << '\n';
cout << type_id_with_cvr<decltype(b2)>().pretty_name() << '\n';
return EXIT_SUCCESS;
}
输出:
Base&
Base2&
相关文章
在 MySQL 中使用 CURRENT_TIMESTAMP 作为默认值
发布时间:2024/03/25 浏览次数:177 分类:MySQL
-
本文教你如何在低于 5.6.5 的 MySQL 版本中使用 CURRENT_TIMESTAMP 作为 DEFAULT。因此,你可以防止 MySQL 错误 1293。我们的方法包括重新排序表列、使用 DEFAULT 0 和时间值。
HTML 中的 JavaScript 时间选择器示例
发布时间:2024/03/20 浏览次数:122 分类:JavaScript
-
JavaScript Time Picker 允许最终用户从直接输入估值器或从弹出窗口中选择时间。时间可以有多种格式,这取决于你需要哪种格式。
C# 获取 Unix 时间戳
发布时间:2024/01/20 浏览次数:245 分类:编程语言
-
本文介绍如何在 C# 中获取 unix 时间戳。它介绍了诸如 DateTime.Now.Subtract().TotalSeconds,DateTimeOffset.Now.ToUnixTimeSeconds()和 TimeSpan Struct 之类的方法
在 Python 中对日期和时间进行排序
发布时间:2023/06/17 浏览次数:125 分类:Python
-
在本文中,我们讨论了如何在 Python 中使用 sorted() 方法对日期和时间进行排序。 为了理解这个概念,我们举了一些例子以及 Python 中的 datetime 模块。
仅将 MySQL 时间戳日期与日期参数进行比较
发布时间:2023/05/09 浏览次数:181 分类:MySQL
-
在本篇文章中我们将使用 DATE() 、CAST() 和 CONVERT() 函数将 MySQL 时间戳日期仅与 date 参数进行比较。