Imm*_*ant 1 c++ virtual runtime compilation typeid
C++ 关键字typeid有一个魔力:它知道何时使用编译时类型信息以及何时使用运行时类型信息:
#include <iostream>
#include <typeinfo>
using namespace std;
struct Interface { virtual void f() = 0; };
struct S1 : Interface { void f() { cout << "S1\n"; }};
struct S3 : S1 { void f() { cout << "S3\n"; }};
int main() {
S1 s1;
cout << typeid(s1).name() << endl;
S1* ps = new S3;
cout << typeid(ps).name() << endl;
cout << typeid(*ps).name() << endl;
delete ps;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
程序打印:
struct S1
struct S1 * __ptr64
struct S3
Run Code Online (Sandbox Code Playgroud)
我的问题: gcc/clang 编译器是否有任何编译器宏或 type_traits :它暴露了typeid魔法并告诉我们typeid(*ps)是编译时确定的还是运行时确定的?
看一下这个:
template<typename T>
constexpr auto my_typeId(const T& value) {
auto compileTimeChecked{ true };
const auto& typeId = typeid(compileTimeChecked = false, value);
return std::pair<
decltype(compileTimeChecked),
decltype(typeId)
>{ compileTimeChecked, typeId };
}
Run Code Online (Sandbox Code Playgroud)
该对的第一个参数trueiftypeid在编译时解析。false否则。第二个成员是对已解析类型信息的引用const std::type_info &
这里的技巧是typeid语义会根据它所采用的参数而变化。如果参数是多态类的实例,则typeid实际上在运行时计算表达式,并且 的副作用发挥作用compileTimeChecked = false。否则typeid不计算表达式(因此,永远不会发生),而只是在编译时compileTimeChecked = false获取解析的静态类型。value
编辑:正如user17732522 在评论中指出的那样,请注意,当value是多态纯右值时,my_typeId函数实际上在运行时对其进行求值,这与typeid如果直接传递则静态解析类型不同。在使用函数时,这种差异显然是不可能消除的,只是因为函数调用在 C++ 中的工作方式。