gpt4 book ai didi

c++ - 打印给定类型名称的模板

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:17:17 24 4
gpt4 key购买 nike

出于调试目的,我想打印一个类型的名称,所以我创建了一个函数来实现这个目的(事实上,我从另一个 SO 答案中借用了它,但我现在找不到),该函数看起来像这样:

template <typename T> std::string TypeName(T)
{
auto name = typeid(T).name();
int status = 0;

std::unique_ptr<char, void(*)(void*)> res {
abi::__cxa_demangle(name, NULL, NULL, &status),
std::free
};

return ((status == 0) ? res.get() : name);
}

Live Demo

它工作正常:

int i = 0;
float f = 0.f;

std::cout << TypeName(i) << '\n'; // int
std::cout << TypeName(f) << '\n'; // float, so far so good

std::cout << TypeName(&i) << '\n'; // int *
std::cout << TypeName(&f) << '\n'; // float *, as expected

但它缺乏处理top-level cv-cualifiers的能力和引用:

const int ci = 1;
const float cf = 1.f;

std::cout << TypeName(ci) << '\n'; // int! (instead of const int)
std::cout << TypeName(cf) << '\n'; // float! (instead of const float)

int &ri = i;
float &rf = f;

std::cout << TypeName(ri) << '\n'; // int! (instead of int &)
std::cout << TypeName(rf) << '\n'; // float! (instead of float &)

嗯,我不能说这是出乎意料的,因为函数 TypeName 是一个函数模板,类型 T 遵循模板类型推导,但是这个问题使得整件事几乎没用。

所以,我的问题是:是否可以做任何事情来创建模板函数(可以获取任何类型作为输入)来获取类型名称而不丢失顶级 cv-cualifiers 和引用?

提前致谢。

最佳答案

唯一 C++ 语言结构可以区分作为id 表达式 的左值和作为引用的左值是decltype。这是一个如何使用它的示例,包括(滥用)使用宏来保持您已有的相同调用模式:

template <typename T> std::string TypeName() {
auto name = typeid(T()).name(); // function type, not a constructor call!
int status = 0;

std::unique_ptr<char, void(*)(void*)> res {
abi::__cxa_demangle(name, NULL, NULL, &status),
std::free
};

std::string ret((status == 0) ? res.get() : name);
if (ret.substr(ret.size() - 3) == " ()") ret.resize(ret.size() - 3);
return ret;
}
#define TypeName(e) TypeName<decltype(e)>()

因为 abi::__cxa_demangle 忽略了顶级 cv 和引用限定符,我们构造了一个函数类型,然后去掉了尾部括号。

这会根据需要给出 int constint&int const&

关于c++ - 打印给定类型名称的模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25891266/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com