为什么 typeid.name() 使用 GCC 返回奇怪的字符以及如何让它打印未损坏的名称?

问题描述 投票:0回答:7

为什么当我运行这个时

main.cpp

#include <iostream>
#include <typeinfo>

using namespace std;

struct Blah {};

int main() {
  cout << typeid(Blah).name() << endl;
  return 0;
}

使用 GCC 版本 4.4.4 进行编译:

g++ main.cpp

我明白了:

4Blah

在 Visual C++ 2008 上,我会得到:

struct Blah

有没有办法让它只打印

Blah
struct Blah

c++ gcc g++ rtti
7个回答
76
投票

name
的返回是实现定义的:甚至不需要实现为不同类型返回不同的字符串。

您从 g++ 中得到的是一个 修饰名称,您可以使用

c++filt
命令或
__cxa_demangle
“解构”它。


19
投票

返回的字符串是实现定义的。

gcc 正在做的是返回损坏的名称。
您可以使用 c++filt 将损坏的名称转换为纯文本

> a.out | c++filt

13
投票

有没有办法让它只打印

Blah
还是
struct Blah

不。

std::typeinfo::name()
的结果未指定。它甚至可能为所有类型返回相同的字符串(或者实际上,为所有类型返回空字符串),并且实现仍然符合标准。您不能依赖其结果。确实,我发现它唯一有用的就是调试。

告诉我们您需要它做什么。通常,您可以使用特征来代替。


8
投票

正如其他人所说,这里的结果是实现定义的,这意味着实现(即编译器工具链)可以自由地定义它,只要它在某处记录即可。

来自 C++ 标准,第 18.5.1/1 节 [lib.type.info]:

type_info
描述了实现生成的类型信息。该类的对象 有效地存储指向类型名称的指针,以及适合比较两种类型的编码值 相等或整理顺序。类型的名称、编码规则和整理顺序均未指定 并且不同程序之间可能有所不同。


6
投票

在 4Blah 中,4 是班级名称中的字母数量。例如,如果您的类名称是 myEmptyClass 那么它将打印 12myEmptyClass。


3
投票

typeid().name()
取决于实现。它甚至可能为每种类型返回空字符串。这不是非常有用的实现,但它是有效的。


1
投票

对于 GCC 使用

./a.out | c++filt --types

欲了解更多信息,请点击链接

© www.soinside.com 2019 - 2024. All rights reserved.