C++ typeid().name()自定义类命名逻辑及输出行为修改
GCC环境下typeid输出的前缀数字规则说明
typeid名称输出的底层逻辑
C标准从未对typeid().name()的输出格式、具体内容做强制约束,你观察到的带数字前缀的输出,本质是GCC/Clang遵循的*Itanium C ABI 名称修饰(Name Mangling)规则*生成的编译期符号名,属于编译器的实现细节,和自定义类的继承关系、成员组成没有关联。
对应你的测试输出拆解:
- 你之前观察到的「数字前缀是类名长度」的规律,对全局命名空间下的简单非模板自定义类是完全成立的:
Student一共7个英文字符,所以修饰名为7StudentPerson一共6个英文字符,所以修饰名为6Person
- 内置基础类型在这套规则里有固定的单字符缩写,和类名的长度前缀规则同属一套体系:
i对应intf对应floatd对应doublel对应longj对应unsigned int
- 对于命名空间嵌套、模板实例化的类型,这套规则会额外增加结构标记,因此输出格式看起来和简单类不同:
你看到的NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE是std::string的修饰名,开头的N代表嵌套名称块开始,St是std命名空间的固定缩写,__cxx11是libstdc++的inline命名空间名(长度7个字符),12basic_string代表长度12的basic_string类名,后面依次是它的三个模板参数的修饰名,最后E代表嵌套块结束。它的格式差异只是因为嵌套/模板类型需要额外的结构编码,并非打破了之前的长度前缀规则。
能否自定义typeid().name()的返回内容
答案是完全无法通过用户代码实现。typeid是C++语言的内置操作符,它返回的std::type_info对象是编译器在编译阶段为每个类型自动生成的全局唯一实例,这个实例的name()方法返回的字符串是编译器在编译期硬编码的符号名,不存在任何用户层接口可以修改它的内部内容——无论你在Person或Student类中实现任何内置方法、静态成员,都无法接触或改写编译器生成的type_info实例的数据。
如果需要自定义类型的名称展示,只能额外封装一套独立的类型标识逻辑:比如为每个类定义一个静态方法返回自定义名称,再通过类型特征(type_traits)或重载机制获取,不能通过修改typeid的默认行为实现。
内容的提问来源于stack exchange,提问作者Visrut
相关产品推荐
相关产品推荐

