问题描述
我正在学习如何在C ++ 11中使用type_traits
,并被告知type_traits
在编译时有效。
我真的很惊讶。我做了如下测试:
class A {virtual void foo();};
class B : public A {};
constexpr bool b = std::is_base_of<A,B>::value;
constexpr bool bb = std::is_polymorphic<A>::value;
constexpr bool bb2 = std::is_polymorphic<B>::value;
int main()
{
return 0;
}
我使用命令g++ -std=c++11 main.cpp -g
编译这段代码,并获得一个二进制文件a.out
。
然后我执行命令objdump -dj .rodata a.out
并获得输出:
./a.out: file format elf64-x86-64
disassembly of section .rodata:
0000000000000830 <_IO_stdin_used>:
830: 01 00 02 00 ....
0000000000000834 <_ZStL19piecewise_construct>:
...
0000000000000835 <_ZL1b>:
835: 01 .
0000000000000836 <_ZL2bb>:
836: 01 .
0000000000000837 <_ZL3bb2>:
837: 01 .
好的,type_traits
确实在编译时起作用。
但是如何?还是这意味着C ++编译器可以在编译时获取所有多态信息?我一直以为多态信息全都与运行时有关...
解决方法
多态类型是其 instances 可以表现出多态行为(虚拟函数调用,类型擦除,RTTI等)的类型。该行为本身在运行时发生,但是这种可能性在编译时就已经知道了-仅因为编译器必须生成启用它的内部数据结构(vtable等)。
例如,给定两个神秘类型X
和Y
:
void check(X const &x) {
if(dynamic_cast<Y *>(&x))
std::cout << "We have a Y!\n";
}
...条件将在运行时通过,前提是Y
是x
的动态类型之一,但是函数本身仅在dynamic_cast
有效的情况下编译,即如果X
和Y
是多态类型。