1

c++filt当我遇到重复的符号错误时,我只是跑去demangle:

$ c++filt __ZN4uiuclsERNSt3__113basic_ostreamIcNS0_11char_traitsIcEEEERKNS_5StackE

uiuc::operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, uiuc::Stack const&)

但实际的函数看起来像这样[在uiuc命名空间内]:

std::ostream & operator<<(std::ostream & os, const Stack & stack)

我怎样才能得到解耦的输出到

  1. 显示返回类型:std::ostream &
  2. 显示std::ostream而不是 std::__1::basic_ostream<char, std::__1::char_traits<char> >&. __之后std::是我没有得到的权利和类似模板的输入。ostream 是作为模板实现的吗?

我问是因为我无法轻松映射其他返回转弯类型。我正在处理一个用于练习的小文件。

我正在运行macOS并尝试了c++filt --format编译器的不同选项,但没有看到任何给我不同输出的选项。

4

1 回答 1

1
  1. 显示返回类型:std::ostream &

普通函数的返回类型不是它们的签名或它们的名字的一部分。无法从损坏的名称中获取返回类型。为此,您需要查找声明该函数的头文件。

但是,对于函数模板,这是不同的。

  1. 显示std::ostream而不是std::__1::basic_ostream<char, std::__1::char_traits<char> >&. __之后std::是我没有得到的权利和类似模板的输入。是ostream作为模板实现的吗?

该标准定义了std::ostream它的类型别名std::basic_ostream<char, std::char_traits<char>>,它是类模板的模板特化std::basic_ostream。对于流可以使用的每种字符类型,都有它的特殊化,例如std::basic_ostream<wchar_t, std::char_traits<wchar_t>>(别名为std::wostream)用于宽字符流。

类型别名在编译期间被解析为它们所引用的实际类型名称,因此经过修改的名称不包含有关在声明中使用的别名的任何信息。区分也是没有意义的,因为无论使用什么别名,功能都应该相同,因此符号名称不能在其上有所不同。

原则上,您可以为标准库的公共别名运行搜索和替换。我不知道有什么工具可以做到这一点。无论如何,您很快就会习惯非别名。

::__1是标准库使用的内联命名空间,能够透明地定义标准库符号的多个版本。可以查找内联命名空间中的名称,就好像它们是在封闭的命名空间中声明的一样,因此当您使用 eg 时std::ostream,库实际上可能ostream不在std命名空间中声明,而是在 中声明,如果是内联命名空间std::__1,仍然可以找到它。__1

这是一个你应该忽略的实现细节。名称中的双下划线很好地表明它是您不需要关心的实现细节,因为带有双下划线的标识符保留供语言实现使用。

同样,您可能可以从标准库名称空间中搜索和替换此类内联名称空间,但我不知道是否有任何工具这样做,而且很快就会习惯它。

于 2020-03-20T10:46:53.403 回答