如何识别变量的类型

时间:2016-04-29 22:39:45

标签: c++ types typeid gettype

如何在c ++中正确识别变量类型。我试着用它来识别一种变量:

int a = 5;
std::cout << typeid(a).name() << std::endl;

而不是预期的输出int,它给你:

i

我很困惑,为什么会发生这种情况..它只是给你一个你声明变量的类型的第一个字母。 Int不是唯一的......也是这样的:

 char a = 'A'
 std::cout << typeid(a).name() << std::endl;

Example Program

这有一个简单的解决方法吗?任何帮助将不胜感激!

3 个答案:

答案 0 :(得分:13)

您的代码有两个问题,

首先df.iloc[df[df.A == 1].index + 1] 返回一个实现定义的字符串,它可以是任何有效的字符串,它可以为每个类型返回typeid(..).name(),它甚至可以为每个程序执行返回不同的值(虽然我相信值在执行期间无法改变)。 GCC(和Clang?)返回不可读的名称,而Visual C ++返回合理的名称(在本例中为""

其次,如果int的类型是多态类型,a将返回与动态类型typeid(a)对应的typeid,而不是用于声明a,而不是a

不幸的是,没有一种标准方法可以以人类可读或正确的C ++语法的方式获取类型的名称。 (如果你想要一种适用于GCC的方法,请参见Unmangling the result of std::type_info::name

编辑使用Boost,您可以尝试typeid(decltype(a)),请参阅Getting human readable and mangled type names

答案 1 :(得分:3)

  

我的意思是即使它不可理解。例如,如果int是32432423423403095590353095309530953,那么它总是会相同的。所以我可以轻松设置一个函数来返回变量的类型......

您获得的结果已经实现了。也许这将有助于解释您正在使用的C ++实现如何获得您所看到的字符串。

g ++实现typeid(...).name(),以便返回该类型的“ABI mangled”名称。这是表示编译对象文件和库中使用的类型的特殊方法。如果将C ++代码编译到汇编中,您将看到“符号”,用于标识生成的汇编代码与哪些函数或数据相关。例如,使用函数:

int foo(double a, char b) {
    return a + b;
}

compile it to assembly,您会看到以下内容:

_Z3foodc:
.LFB0:
    .cfi_startproc
    movsbl  %dil, %edi
    cvtsi2sd    %edi, %xmm1
    addsd   %xmm1, %xmm0
    cvttsd2si   %xmm0, %eax
    ret
    .cfi_endproc

这里的第一行是'mangled'符号,用于标识函数int foo(double,char)。它包含表示函数名称的“Z3foo”,然后是表示第一个参数类型的“d”和表示第二个参数类型的“c”。此符号用于标识二进制对象文件中的函数,库索引中的函数,以及要链接到此函数的其他编译对象等。

您还可以使用c ++ filt工具demangle symbols。此工具会扫描您传递给它的任何文本,查找符合修改语法的内容,并将它们转换为更类似于在C ++源代码中命名这些类型的方式。

g ++实现了Itanium C++ ABI修改方案。它被大多数unix平台编译器使用。

所以,回到你的代码,猜猜在这些符号中如何表示'int'类型。

Itanium ABI specifies是解码的附加功能。 Here's使用它的一个例子。

答案 2 :(得分:2)

类型名称不应该是您期望的类型。有关获取实际类型名称的方法,请参阅this answer。注意 - 它仅适用于gcc,并且在某些additional installation上适用于clang。

使用Visual C ++,您应该调用UnDecorateSymbolName,但显然ints are called int there