2011-09-25 48 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; 
} 
相关问题