打印给定类型的名称的模板 [英] Template which prints the name of the given type
问题描述
我想打印一个类型的名称为调试目的,所以我创建了一个函数做的伎俩(事实上,我借用它从另一个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);
}
它工作正常:
int i = 0;
float f = 0.f;
std :: cout<< TypeName(i)<< '\\\
'; // int
std :: cout<< TypeName(f)<< '\\\
'; // float,so far so good
std :: cout<< TypeName(& i)<< '\\\
'; // int *
std :: cout<< TypeName(& f)<< '\\\
'; // float *,正如预期的
但它缺少处理顶级流标和参考文献:
const int ci = 1;
const float cf = 1.f;
std :: cout<< TypeName(ci)<< '\\\
'; // int! (而不是const int)
std :: cout<< TypeName(cf)<< '\\\
'; // float! (而不是const float)
int& ri = i;
float& rf = f
std :: cout<< TypeName(ri)<< '\\\
'; // int! (而不是int&)
std :: cout<< TypeName(rf)<< '\\\
'; // float! (而不是float&)
好吧,我不能说这是意想不到的,因为函数 TypeName
是一个函数模板,类型 T
遵循模板类型扣除,但这个问题使整个事情几乎无用。
所以,我的问题是:有没有什么可以做,以创建一个模板函数(可以获得任何类型作为输入)获取类型名称
只有 C ++语言结构可以判断为一个 id-expression 的左值和作为引用的左值之间的差异 decltype
。下面是一个如何使用它的例子,包括(ab)使用宏来保持你已经拥有的相同的调用模式:
template< typename T> std :: string TypeName(){
auto name = typeid(T())。 //函数类型,不是构造函数调用!
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)>()
$ b b
因为 abi :: __ cxa_demangle
忽略顶级cv和引用限定符,我们构造一个函数类型,然后剥去尾括号。
这会给出 int const
, int&
, int const& ;
I would like to print the name of a type for debugging purposes, so I've created a function which does the trick (in fact, I borrowed it from another SO answer, which I cannot found now), the function looks like this:
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);
}
It works fine:
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
But it lacks of the capacity of dealing with top-level cv-cualifiers and references:
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 &)
Well, I can't say that this is unexpected, because the function TypeName
is a function template and the type T
follows the template type deduction but this issue makes the whole thing almost useless.
So, my question is: Is there anything that can be done in order create a template function (which can get any type as input) to obtain the type name without loosing the top-level cv-cualifiers and references?
Thanks in advance.
The only C++ language construct that can tell the difference between an lvalue that is an id-expression and an lvalue that is a reference is decltype
. Here's an example of how to use it, including (ab)use of a macro to keep the same calling pattern you already have:
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)>()
Because abi::__cxa_demangle
ignores top-level cv and reference qualifiers, we construct a function type and then strip the trailing brackets.
This gives int const
, int&
, int const&
as required.
这篇关于打印给定类型的名称的模板的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!