当在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
字符串
我认为在编译时,当函数被示例化时,类型应该是可用的,但是我对模板不太熟悉,我还没有看到一种方法可以将类型作为字符串获取。
我想这样做的原因是为了一些printf类型的调试。我有多个线程在运行,用gdb单步执行会改变程序的行为。所以对于一些事情,我想转储有关哪些函数正在执行的信息。这并不太重要,所以如果解决方案过于复杂,我会跳过将此信息添加到日志函数中。但是如果有一种简单的方法来做到这一点,它将是有用的信息要有。
7条答案
按热度按时间kb5ga3dv1#
获取一个有用的编译时名称:
假设你有一个名为'T'的未知类型。你可以通过糟糕地使用它来让编译器打印它的类型。例如:
字符串
错误消息如下:
型
“in”后面的位显示类型。(仅用clang测试)。
其他触发方式:
型
在C++11中,你可能已经有了一个对象,并使用
decltype
来获取它的类型,所以你也可以运行:型
lymgl2op2#
__PRETTY_FUNCTION__
应该可以解决您的问题(至少在运行时)下面程序的输出是:
字符串
如果你真的,真的,需要将类型字符串作为字符串,你可以破解这个(使用
snprintf
而不是printf
),并拉取'='之后和''之前的子字符串。型
z8dt9xmd3#
另一个编译时解决方案,类似于matiu提供的解决方案,但可能更具描述性,是使用 Package 在一个小助手函数中的
static_assert
:个字符
上面会给予你一个很好的错误消息(在MSVC和Clang中测试过),就像在另一个答案中一样,但在我看来,代码更容易理解。
注意:原始答案中的代码格式不正确,所以我稍微修改了一下代码。
always_false
的功劳归于this答案。s4chpxco4#
既然你说你需要它用于调试目的,也许运行时解决方案也是可以接受的。你已经把它标记为g++,所以你不想符合标准。
这意味着:
字符串
编辑:修正了内存泄漏。感谢杰西。
6yoyoihd5#
有Boost.TypeIndex库。
详情请参见boost::typeindex::type_id。
它非常易于使用,跨平台,是真实的编译型解决方案。即使没有RTTI可用,它也能正常工作。此外,大多数编译器都支持。
4jb9z9bj6#
你可以使用C++20的
concept
s来定义一个任何类型都不能满足的约束。在模板参数上使用这个约束并示例化模板将导致编译器失败并打印出推导出的类型。字符串
如果你的
T
更复杂,例如T=std::vector<std::pair<key_t, value_t>>
或T=void (*)(U, V const&)
,你想具体找出key_t
或V
,你可以这样做:型
rslzwgfq7#
如果你不在乎语句会破坏编译,最简单的方法是:
字符串
没有办法在不破坏编译的情况下打印类型。(当然你可以触发一个警告,而不是这里的错误)