如何将模板类型名称作为字符串获取?

3
以下代码在调用模板函数时打印出字符串"T"而不是实际的类型名称。是否有一种方法可以在不添加任何东西到被模板化的类型中的情况下获取真正的类型名称?
#define stringify(a) #a
#define tostring(a) stringify(a)

template <typename T>
void function_foo(T a, T b)
{
    cout << tostring(T) << endl;
    ...
}

1
请参见此处:https://dev59.com/dHI_5IYBdhLWcg3wMf9_ - Abhay
如何在C++中将typename T转换为字符串? - Industrial-antidepressant
4个回答

3

模板不是那样工作的。在你的模板中,T 指定了一种类型,而不是一系列标记:

typedef int lolztype;
typedef int lulztype;

function_foo<lolztype>(0, 0);
function_foo<lulztype>(0, 0); // calls the *same* template

无法分别获取lolztypelulztype。您可以尝试使用typeid(T).name(),但这并没有太大帮助,因为它不需要人类可读,也不需要对每种类型都不同。

你可以尝试使用geordi的文件type_strings.hpp,在使用GCC编译时可以打印出人类可读的字符串。


你的意思是两种类型可能具有相同的内部二进制表示,但不同的定义/声明可能具有相同的typeid().name()吗? - Stephane Rolland
@Stephane 这完全没有具体说明。 - Johannes Schaub - litb
@Stephane:他的意思是(例如)intstd::vector<double>可能具有相同的type_info::name() - Steve Jessop
好的,所以根据编译器的实现方式,不能保证有趣的结果。 - Stephane Rolland
@HelloGoodbye 有趣?以什么方式?也许你是指令人愉悦、有趣、好奇,可能只有几秒钟。最多 :) - Stephane Rolland
显示剩余2条评论

1

使用:

#include <typeinfo>

template <typename T>
void function_foo(T a, T b)
{
    cout << typeid(a).name() << endl;
    ...
}

typeid().name() 返回的内容取决于平台,但是它是一个字符串,可能代表您的类型。


这实际上在技术上是不正确的。来自手册:“返回一个可能标识类型的空终止字符序列。”因此,它实际上可能或可能不会“表示您的类型”。 - Chris Kitching
1
如果字符串可以用于标识类型,那么从技术上讲它是否代表该类型? - HelloGoodbye
@ChrisKitching 我已经被告知多次不要参考 www.cplusplus.com 的文档,因为其质量可能不是最优的。请查看 https://en.cppreference.com/w/cpp/types/type_info/name 。 - Stephane Rolland

1

有一个typeid运算符。但要注意,name()字符串是实现定义的。特别地,它通常涉及到一些名称修饰。一些实现还提供了另一个公共方法来获取更好的字符串;请检查你的<typeinfo>头文件。

#include <typeinfo>
template <typename T>
void function_foo(T a, T b)
{
    std::cout << typeid(a).name() << std::endl;
    // ...
}

1
你唯一的选择是自己定义这个反射,也许可以通过一个接口来返回其具体类型的字符串表示形式。
struct my_type : public reflects {
    my_type();
    static const std::string& type_name = "my_type";
};

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接