2011-09-25 85 views
2

我希望能夠在模板化類中創建一個方法,該方法返回模板參數中提供的類型名稱。獲取模板參數的字符串表示形式

如:

template <typename T> 
class CPropertyValueT 
{ 
    std::string GetTypeName() 
    { 
    return #T; 
    } 
} 

這是可能使用#預處理宏,我想通都必須有模板的方式。

這可能嗎?

回答

6

您可以使用typeid(T).name(),雖然它會返回裝飾該類型的名稱。

如果您使用的是GCC,那麼您可以使用在cxxabi.h標題中聲明的GCC API來對這些名稱進行解構。

下面是一個例子(source):

#include <exception> 
#include <iostream> 
#include <cxxabi.h> 

struct empty { }; 

template <typename T, int N> 
    struct bar { }; 


int main() 
{ 
    int  status; 
    char *realname; 

    // exception classes not in <stdexcept>, thrown by the implementation 
    // instead of the user 
    std::bad_exception e; 
    realname = abi::__cxa_demangle(e.what(), 0, 0, &status); 
    std::cout << e.what() << "\t=> " << realname << "\t: " << status << '\n'; 
    free(realname); 


    // typeid 
    bar<empty,17>   u; 
    const std::type_info &ti = typeid(u); 

    realname = abi::__cxa_demangle(ti.name(), 0, 0, &status); 
    std::cout << ti.name() << "\t=> " << realname << "\t: " << status << '\n'; 
    free(realname); 

    return 0; 
} 

輸出:

St13bad_exception  => std::bad_exception : 0 
    3barI5emptyLi17EE  => bar<empty, 17>  : 0 

另一個有趣的鏈路描述中GCC和Microsoft VC++ demangling:

+0

很好的答案,這是最好的一個可以做的。但值得注意的是,name()並沒有強制返回標準有意義的內容,所以這是一個QOI問題。 –

+0

@ArmenTsirunyan:是的。順便說一句,我增加了更多的東西給我的答案。 – Nawaz

0
#include <cstdlib> 
#include <typeinfo> 
#include <iostream> 

using namespace std; 

template <typename T> 
class CPropertyValueT 
{ 
public: 
    std::string GetTypeName() 
    { 
    return std::string(typeid(T).name()); 
    } 
}; 

int main() 
{ 
    CPropertyValueT<float> x; 

    cout << x.GetTypeName(); 

    return 0; 
} 
相關問題