简体   繁体   中英

How to check if a c++ typeid(T) call is compile time or runtime determined?

C++ keyword typeid has a magic: it know when to use compile-time type info and when to use runtime type info:

#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;
}

The program prints:

struct S1
struct S1 * __ptr64
struct S3

My question: does gcc/clang compiler has any compiler macro, or type_traits: that exposes typeid magic and tells us whether typeid(*ps) is compile-time determined or runtime-determined?

Check this out:

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 };
}

The first argument of the pair has true if typeid is resolved at compile time. false otherwise. The second member is the reference to the resolved type information const std::type_info &


The trick here is that typeid semantic changes depending on the argument it takes. If argument is an instance of a polymorphic class, then typeid actually evaluates the expression in runtime, and the side effect of compileTimeChecked = false comes into play. Otherwise typeid does not evaluate the expression (thus, compileTimeChecked = false never happens), but just takes the static type of value resolved at compile-time.

Edit : as pointed out by user17732522 in the comments , be advised that when value is a polymorphic prvalue, my_typeId function actually evaluates it in runtime, unlike the typeid which, if passed directly, resolves the type statically. This difference is apparently impossible to get rid of when using functions, just because of how function call work in C++.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM