用我们的决心、信心和毅力来培植我们的生命之|

3的4次方

园龄:2年1个月粉丝:5关注:89

2024-07-14 23:20阅读: 154评论: 0推荐: 0

C++获取类型名称的技巧

C++获取类型名称的技巧

在某些情况下,我们需要明确知道编译器推导出的类型,特别是复杂类型。这些类型信息对于调试、优化和确保代码正确性非常重要。

技巧1:在编译期确定类型

主要用于模板编程和泛型编程时。

在编译期间确定类型的一种方法是通过引发编译错误,查看编译器的错误信息

示例:如何通过引发编译错误查看类型

template<typename T>
class TypeDisplayer; // 提供一个没有定义的辅助模板类,用于引发编译时模板实例化错误
int main() {
auto a = 10;
auto b = &a;
TypeDisplayer<decltype(a)> aType;
TypeDisplayer<decltype(b)> bType;
}

在这种情况下,编译器会报告错误,显示 ab 的实际类型。这种方法特别适合在开发过程中快速查看类型推导结果,而不需要额外的工具:

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 的类型是 intb 的类型是 int*

技巧2:在运行时确定类型

主要用于动态类型系统或多态性场景中。

typeid 操作符生成一个 std::type_info 对象,而 std::type_infoname 成员函数会返回一个描述类型名称的字符串。

示例:使用 typeidstd::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 提供更准确的类型信息

typeidstd::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 中国大陆许可协议进行许可。

posted @   3的4次方  阅读(154)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起