2011-09-19 112 views
4

我想獲取類型名稱並打印出來用於調試目的。我使用下面的代碼:在C++編譯時獲取類型名稱

#include <cxxabi.h> 

inline const char* demangle(const char *s) { 
    abi::__cxa_demangle(s, 0, 0, NULL); 
} 

template<typename T> 
inline const char* type_name() { 
    return demangle(typeid(T).name()); 
} 

它運行良好,但它我認爲有不必要的運行時間開銷。有沒有什麼辦法可以獲得編譯時計算出來的類型爲ID的人類可讀形式?我正在考慮看起來像這樣的東西:

boost::mpl::type_name<MyType>::value 

這將返回類型名稱的字符串常量。

作爲一個(不是很嚴格)相關的問題:是否有可能使用boost :: mpl進行字符串處理?

+0

請一次提出一個問題。 –

回答

5

我看不到typeid(T).name()會導致運行時間開銷。 typeid(expr)是的,如果expr屬於多態類型。

它看起來像demangling可能發生在運行時,但並沒有太多可以做的事情。如果這只是爲了調試,那麼我真的不會擔心它太多,除非你的分析器表明這導致你的程序放慢速度,以至於調試其它元素都很麻煩。

+0

是的,我問是否可以在編譯時進行解除匹配。 – petersohn

+0

@petersohn:這是「是否」! –

+0

在編譯時無法完成取消。由於C++ ABI與操作系統進行通信的方式(http://en.wikipedia.org/wiki/Name_mangling#Standardised_name_mangling_in_C.2B.2B段落「C++中的標準化名稱修改」) – Marcin

1

你可以使用std :: type_index來緩存demangled字符串。

1

您可以使用std :: map或類似的數據結構(例如展示樹)來相對快速地緩存和訪問demangled名稱。雖然在編譯時沒有完成,但我懷疑後者是可能的。

2

我有同樣的需要,我已經使用__ 功能 __ maccro在我的類的靜態方法來解決它。 但是您必須對__ 功能 __做一些runtine計算來提取類名。你必須做一些模板技巧,以避免在每個類中粘貼相同的代碼。如果有人有什麼要求,我可以清理並將我的代碼從法文翻譯過來。

該方法的主要優點在於您不需要啓用RRTI即可啓用。另一方面,類名的提取可能依賴於編譯器。