C++获取类型名称的技巧
C++获取类型名称的技巧
在某些情况下,我们需要明确知道编译器推导出的类型,特别是复杂类型。这些类型信息对于调试、优化和确保代码正确性非常重要。
技巧1:在编译期确定类型
主要用于模板编程和泛型编程时。
在编译期间确定类型的一种方法是通过引发编译错误,查看编译器的错误信息。
示例:如何通过引发编译错误查看类型
template<typename T> class TypeDisplayer; // 提供一个没有定义的辅助模板类,用于引发编译时模板实例化错误 int main() { auto a = 10; auto b = &a; TypeDisplayer<decltype(a)> aType; TypeDisplayer<decltype(b)> bType; }
在这种情况下,编译器会报告错误,显示 a
和 b
的实际类型。这种方法特别适合在开发过程中快速查看类型推导结果,而不需要额外的工具:
error: aggregate 'TypeDisplayer<int> aType' has incomplete type and cannot be defined error: aggregate 'TypeDisplayer<int *> bType' has incomplete type and cannot be defined
这告诉我们 a
的类型是 int
,b
的类型是 int*
。
技巧2:在运行时确定类型
主要用于动态类型系统或多态性场景中。
typeid
操作符生成一个 std::type_info
对象,而 std::type_info
的 name
成员函数会返回一个描述类型名称的字符串。
示例:使用 typeid
和 std::type_info::name
可以在运行时获取类型信息
#include <iostream> #include <typeinfo> #include <cxxabi.h> struct Base { virtual ~Base() {} }; struct Derived : public Base { Derived() {} }; std::string demangle(const char* name) { int status = -4; // Some arbitrary value to eliminate the compiler warning char* real_name = abi::__cxa_demangle(name, NULL, NULL, &status); std::string result = (status == 0) ? real_name : name; free(real_name); return result; } int main() { Base* p = new Derived(); const std::type_info& ti_stc = typeid(p); // 静态类型 const std::type_info& ti_dyn = typeid(*p);// 动态类型 std::cout << "Static type of p is: " << demangle(ti_stc.name()) << std::endl; // 输出 Base* std::cout << "Dynamic type of p is: " << demangle(ti_dyn.name()) << std::endl;// 输出 Derived delete p; return 0; }
注意:
typeid(p)
获取的是指针本身的类型信息,即Base*
的类型信息,这被称为静态类型。typeid(*p)
获取的是指针p
所指向的对象的实际类型信息,即动态类型。如果p
指向的是一个Derived
对象,那么typeid(*p)
将会返回Derived
的类型信息。
关键在于,当你对指针进行解引用 *p
时,你实际上是在访问指针所指向的对象。如果这个对象是通过继承层次结构创建的(即 p
是一个多态指针),那么你得到的就是那个具体对象的类型信息。
技巧3:使用 Boost.TypeIndex 提供更准确的类型信息
typeid
和 std::type_info::name
在某些情况下可能不会显示完整的类型信息,特别是在处理引用和 const
限定符时。使用 Boost.TypeIndex
库可以提供更准确的类型信息,保留所有的类型限定符:
#include <boost/type_index.hpp> #include <iostream> #include <vector> template<typename T> void process(const T& param) { using boost::typeindex::type_id_with_cvr; std::cout << "T = " << type_id_with_cvr<T>().pretty_name() << '\n'; std::cout << "param = " << type_id_with_cvr<decltype(param)>().pretty_name() << '\n'; } std::vector<int> generateVector() { return {1, 2, 3}; } int main() { const auto myVector = generateVector(); if (!myVector.empty()) { process(&myVector[0]); } return 0; }
本文作者:3的4次方
本文链接:https://www.cnblogs.com/3to4/p/18302198
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
分类:
标签:
,
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步