如何在C++类方法中获取当前类的类型?
C++类方法中通过this类型动态获取打印内容的编译错误修复
问题背景
想要在类方法中根据this的类型,从映射表中取出对应的字符串打印,但原代码出现三类编译错误:
decltype相关语法错误std::declval触发的断言错误Base类缺少operator<导致std::map无法工作
错误原因分析
- 类型误用:原代码试图直接将
std::remove_reference<decltype(*this)>::type(这是一个类型)作为std::map的key,但std::map的operator[]和at()需要的是对象实例,而非类型本身,这是核心逻辑错误。 - std::declval使用错误:
std::declval仅用于模板元编程中获取类型的右值引用,不能用来创建实际的对象实例,用它初始化map元素会导致构造错误。 - std::map的key要求未满足:
std::map的key必须支持比较操作(默认需要operator<),原Base类未定义该运算符,导致map无法正常工作。
修复方案与代码示例
核心思路
改用**类型信息对象(std::type_index)**作为std::map的key,通过typeid(*this)获取当前对象的类型信息,以此作为索引从映射表中取出对应字符串。
修复后的完整代码
#include <iostream> #include <map> #include <typeindex> class Base { public: // 添加虚析构函数(好习惯,若需多态场景下识别实际类型则必须) virtual ~Base() = default; }; // 用std::type_index作为key,存储类型到字符串的映射 using getPrintString = std::map<std::type_index, std::string>; class A : public Base { public: void print(getPrintString& stringMap) { // 获取当前对象的类型信息,包装为可比较的type_index auto typeKey = std::type_index(typeid(*this)); std::string toPrint = stringMap.at(typeKey); std::cout << toPrint << std::endl; } }; class B : public Base { public: void print(getPrintString& stringMap) { auto typeKey = std::type_index(typeid(*this)); std::string toPrint = stringMap.at(typeKey); std::cout << toPrint << std::endl; } }; // 初始化映射表,直接用type_index包装各类型的type_info getPrintString stringMap{ {std::type_index(typeid(A)), "A String"}, {std::type_index(typeid(B)), "B String"} }; int main() { A a; B b; a.print(stringMap); b.print(stringMap); return 0; }
关键修复点说明
- 语法错误修复:用
std::type_index(typeid(*this))替换原类型作为key,typeid(*this)返回当前对象的std::type_info,std::type_index将其包装为可比较的对象,符合std::map的key要求。 - std::declval问题修复:直接用
std::type_index(typeid(类名))初始化map元素,无需使用std::declval创建无效对象。 - operator<问题修复:
std::type_index内部已实现比较逻辑,无需为Base类重载operator<。 - 正确获取this类型:在非虚函数中,
typeid(*this)返回当前方法所属类的静态类型(正好符合需求);若需要多态场景下的实际运行时类型,只需保证Base类有虚函数(如示例中的虚析构)即可。
内容的提问来源于stack exchange,提问作者ad99
相关产品推荐
相关产品推荐

