首頁 >後端開發 >C++ >如何從'std::type_info”中解開損壞的 C 類型名稱?

如何從'std::type_info”中解開損壞的 C 類型名稱?

Mary-Kate Olsen
Mary-Kate Olsen原創
2024-12-27 20:25:10236瀏覽

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