例如:
int a = 12;
cout << typeof(a) << endl;
Run Code Online (Sandbox Code Playgroud)
预期产量:
int
Run Code Online (Sandbox Code Playgroud) 在C++中创建模板函数时,有一种简单的方法可以将模板的类型名称表示为字符串吗?我有一个简单的测试用例来展示我正在尝试做的事情(注意显示的代码不能编译):
#include <stdio.h>
template <typename type>
type print(type *addr)
{
printf("type is: %s",type);
}
int main()
{
int a;
print(&a);
}
// Would like to print something like:
// type is: int
Run Code Online (Sandbox Code Playgroud)
我认为在实例化函数时,typename应该在编译时可用,但我不熟悉模板,我还没有看到将typename作为字符串的方法.
我想这样做的原因是一些printf类型的调试.我有多个线程正在运行,并通过gdb逐步更改程序行为.所以对于某些事情,我想转储有关正在执行哪些函数的信息.这不是太重要,所以如果解决方案过于复杂,我会跳过将此信息添加到我的日志记录功能中.但如果有一种简单的方法可以做到这一点,那将是有用的信息.
无论如何,在typeid禁用RTTI的情况下从GCC 获取编译时信息?在Visual Studio下const char* typeName = typeid(int).name();,即使禁用了RTTI ,一个简单的命令也会适当地返回"int".不幸的是,海湾合作委员会不能这样做.当我尝试在typeid没有RTTI的情况下打电话时,我的程序崩溃了.我知道禁用RTTI不是标准的一部分,但无论如何我是否可以强制GCC进行已知类型的编译时间分辨率?
出于性能原因,RTTI被禁用.我不需要运行时RTTI.
编辑:
这就是我最终的目标:
template<typename T> const char* TypeName(void);
template<typename T> const char* TypeName(T type) { return TypeName<T>(); }
#define REFLECTION_REGISTER_TYPE(type) \
template <> const char* TypeName<type>(void) { return #type; }
Run Code Online (Sandbox Code Playgroud)
它需要REFLECTION_REGISTER_TYPE为每个需要反射信息的类型调用.但只要它被称为每个必需的类型,调用TypeName<int>工作完美.我还添加了函数TypeName(T type),这意味着你可以做这样的事情:int x = 0; printf(TypeName(x));它将打印出"int".GCC应该能够像VC++一样在编译时实现这一点.
有许多方法可以实现一个has_type<T>模板,推断出是否T有一个嵌套类或者命名为typedef type.即
namespace detail {
template<typename> struct tovoid { typedef void type; };
}
template<typename T, typename = void> struct has_type
: std::false_type { };
// this one will only be selected if C::type is valid
template<typename C> struct has_type<C, typename detail::tovoid<typename C::type>::type>
: std::true_type { };
Run Code Online (Sandbox Code Playgroud)
要么
template <typename C> char test_for_type(...) { return '0'; }
template <typename C> double test_for_type(typename C::type const *) { return 0.0; }
template <typename T> struct has_type
{ …Run Code Online (Sandbox Code Playgroud) 我想打印类型的名称以进行调试,所以我创建了一个函数来实现这个目的(事实上,我从另一个答案借用了它,我现在找不到),该函数如下所示:
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);
}
Run Code Online (Sandbox Code Playgroud)
它工作正常:
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 …Run Code Online (Sandbox Code Playgroud) c++ ×5
templates ×2
c ×1
c++11 ×1
g++ ×1
gcc ×1
reflection ×1
type-traits ×1
typeof ×1
variables ×1