是否可以从C++中的模板类型中获取char*名称

Ros*_*sco 10 c++ string templates typeid

我想获取模板类型的字符串名称(const char*).不幸的是我无法访问RTTI.

template< typename T >
struct SomeClass
{
    const char* GetClassName() const { return /* magic goes here */; }
}
Run Code Online (Sandbox Code Playgroud)

所以

SomeClass<int> sc;
sc.GetClassName();   // returns "int"
Run Code Online (Sandbox Code Playgroud)

这可能吗?我找不到办法,即将放弃.谢谢您的帮助.

Joh*_*itb 13

不,它也无法使用typeid可靠.它将为您提供一些取决于编译器实现的内部字符串.像"int"这样的东西,也是"i"的东西很常见int.

顺便说一句,如果你想要的只是比较两种类型是否相同,你不需要先将它们转换为字符串.你可以这样做

template<typename A, typename B>
struct is_same { enum { value = false }; };

template<typename A>
struct is_same<A, A> { enum { value = true }; };
Run Code Online (Sandbox Code Playgroud)

然后呢

if(is_same<T, U>::value) { ... }
Run Code Online (Sandbox Code Playgroud)

Boost已经有了这样一个模板,下一个C++标准也会有std::is_same.

手动注册类型

你可以专注于这样的类型:

template<typename> 
struct to_string {
    // optionally, add other information, like the size
    // of the string.
    static char const* value() { return "unknown"; }
};

#define DEF_TYPE(X) \
    template<> struct to_string<X> { \
        static char const* value() { return #X; } \
    }

DEF_TYPE(int); DEF_TYPE(bool); DEF_TYPE(char); ...
Run Code Online (Sandbox Code Playgroud)

所以,你可以像使用它一样

char const *s = to_string<T>::value();
Run Code Online (Sandbox Code Playgroud)

当然,如果您希望在类型未知的情况下获得编译时错误,也可以删除主模板定义(并仅保留前向声明).我把它包括在这里完成.

我之前使用过char const*的静态数据成员,但它们会导致一些复杂的问题,比如在哪里放置声明的问题,等等.像上面这样的类专业化很容易解决问题.

自动,取决于GCC

另一种方法是依赖编译器内部.在GCC中,以下给出了合理的结果:

template<typename T>
std::string print_T() {
    return __PRETTY_FUNCTION__;
}
Run Code Online (Sandbox Code Playgroud)

回来std::string.

std::string print_T() [with T = std::basic_string<char, std::char_traits<char>, std::allocator<char> >]

一些substr混合的魔法find将为您提供您寻找的字符串表示.