我目前正在编写一些日志代码,这些代码应该 - 除其他外 - 打印有关调用函数的信息。这应该比较容易,标准 C++ 有一个 type_info
类。这包含 typeid 的类/函数/等的名称。但它被破坏了。它不是很有用。即 typeid(std::vector<int>).name()
返回 St6vectorIiSaIiEE
。
有没有办法从中产生有用的东西?就像 std::vector<int>
上面的例子。如果它只适用于非模板类,那也没关系。
该解决方案应该适用于 gcc,但如果我可以移植它会更好。它是用于记录的,所以它不是很重要,不能关闭,但它应该有助于调试。
原文由 terminus 发布,翻译遵循 CC BY-SA 4.0 许可协议
鉴于这个问题/答案受到的关注,以及来自 GManNickG 的宝贵反馈,我已经稍微清理了代码。给出了两个版本:一个具有 C++11 特性,另一个具有 C++98 特性。
在文件 类型.hpp
在文件 type.cpp 中(需要 C++11)
用法:
它打印:
ptr_base 的类型:
Base*
指针类型:
Derived
在 Linux 64 位和 g++ 4.7.2(Mingw32、Win32 XP SP2)上使用 g++ 4.7.2、g++ 4.9.0 20140302(实验性)、clang++ 3.4(主干 184647)、clang 3.5(主干 202594)进行了测试。
如果你不能使用 C++11 的特性,这里是在 C++98 中可以做到的,文件 type.cpp 现在是:
(2013 年 9 月 8 日更新)
接受的答案(截至 2013 年 9 月 7 日) ,当调用
abi::__cxa_demangle()
成功时, 返回一个指向本地堆栈分配数组的指针……哎呀!另请注意,如果您提供缓冲区,
abi::__cxa_demangle()
假定它是在堆上分配的。在堆栈上分配缓冲区是一个错误(来自 gnu 文档): “如果output_buffer
不够长,则使用realloc
扩展它。” 在指向堆栈的指针上调用realloc()
……哎呀! (另见 Igor Skochinsky 的善意评论。)您可以轻松验证这两个错误:只需将已接受答案(截至 2013 年 9 月 7 日)中的缓冲区大小从 1024 减少到更小的值,例如 16,并为其命名 不 超过 15 的名称(所以
realloc()
没有 被调用)。尽管如此,根据您的系统和编译器优化,输出将是:垃圾/无/程序崩溃。要验证第二个错误:将缓冲区大小设置为 1,并使用名称超过 1 个字符的名称调用它。当你运行它时,程序几乎肯定会崩溃,因为它试图用指向堆栈的指针调用
realloc()
。(2010 年 12 月 27 日的旧答案)
对 KeithB 的代码 所做的重要更改: 缓冲区必须由 malloc 分配或指定为 NULL。 不要在堆栈上分配它。
检查该状态也是明智的。
我没找到
HAVE_CXA_DEMANGLE
。我检查了__GNUG__
虽然这并不能保证代码甚至可以编译。有人有更好的主意吗?