首页 >后端开发 >C++ >如何从'std::type_info”中解开损坏的 C 类型名称?

如何从'std::type_info”中解开损坏的 C 类型名称?

Mary-Kate Olsen
Mary-Kate Olsen原创
2024-12-27 20:25:10240浏览

How Can I Demangle Mangled C   Type Names from `std::type_info`?

从 std::type_info 破译神秘的名称

在 C 领域,std::type_info 提供了对实体类型的重要见解,以类为例实例或函数。然而,这种类型名称的混乱表示常常掩盖了它的真实身份。例如,typeid(std::vector).name() 产生“St6vectorIiSaliEE”,使其只能通过精明的头脑或神秘的算法来破译。

揭开谜团

驯服对于这个被破坏的野兽,我们提出了一个解决方案,该解决方案采用了强大的破坏能力std::demangle,一个强大的工具,用于揭示底层类型的人类可读形式。以下是使用此解决方案的分步指南:

  1. type.hpp:使用以下声明建立基础头文件:
#include <string>
#include <typeinfo>

std::string demangle(const char* name);

template <class T>
std::string type(const T& t) {
    return demangle(typeid(t).name());
}
  1. type.cpp (C 11):利用 C 11 功能进行高效的拆解操作:

    #ifdef __GNUG__
    #include <cstdlib>
    #include <memory>
    #include <cxxabi.h>
    
    std::string demangle(const char* name) {
    int status = -4;
    std::unique_ptr<char, void(*)(void*)> res {
    abi::__cxa_demangle(name, NULL, NULL, &status),
    std::free
    };
    
    return (status==0) ? res.get() : name ;
    }
    
    #else
    std::string demangle(const char* name) {
    return name;
    }
    #endif
  2. type.cpp (C 98):为系统提供替代解决方案不含 C 11功能:

    #ifdef __GNUG__
    #include <cstdlib>
    #include <memory>
    #include <cxxabi.h>
    
    struct handle {
    char* p;
    handle(char* ptr) : p(ptr) { }
    ~handle() { std::free(p); }
    };
    
    std::string demangle(const char* name) {
    
    int status = -4; // some arbitrary value to eliminate the compiler warning
    
    handle result( abi::__cxa_demangle(name, NULL, NULL, &status) );
    
    return (status==0) ? result.p : name ;
    }
    
    #else
    
    // does nothing if not g++
    std::string demangle(const char* name) {
    return name;
    }
    
    #endif
  3. 用法:将解决方案集成到您的代码中,轻松提取人类可读的类型名称:

    #include <iostream>
    #include "type.hpp"
    
    struct Base { virtual ~Base() {} };
    struct Derived : public Base { };
    
    int main() {
    Base* ptr_base = new Derived(); 
    std::cout << "Type of ptr_base: " << type(ptr_base) << std::endl;
    std::cout << "Type of pointee: " << type(*ptr_base) << std::endl;
    delete ptr_base;
    }

利用这种方法,以下输出是制作:

Type of ptr_base: Base*
Type of pointee: Derived

兼容性和注意事项
提供的解决方案已在各种平台和编译器上进行了测试,包括 g 、 clang 和 Mingw32。尽管它主要针对 g ,但 C 98 版本也可以在非 g 系统上使用。需要注意的是,特定于供应商的 API 可能会相应地有所不同。

总之,这种破坏解决方案使您能够轻松地从 std::type_info 中提取人类可读的类型名称,从而消除与破坏表示相关的模糊性。通过利用提供的代码片段,您可以将此功能无缝集成到您的项目中,从而清晰、轻松地增强调试和日志记录功能。

以上是如何从'std::type_info”中解开损坏的 C 类型名称?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn