Compile-time type identification

Yesterday I was working on a class to produce natural-language translations of complex C++ types, and I said that there was no general way to map a fundamental type to a name. Of course, there is:

template<typename T>
class TypeDecryptor {
public:
    static string getName() {
        return typeid(T).name();
    }
};

Of course, not quite everything in the garden is lovely. This provides an implementation-defined string, which as far as I can see is not even required to be unique for a given type. In point of fact, it’s extremely unlikely an implementation will return a non-unique string since each type has to be mapped to a string for linkage purposes anyway. The problem is that the string isn’t necessarily human-readable.

I think that on reasonable implementations there should be a function available to unmangle this string back into a human-readable type, which means you can potentially make a completely general type decryptor.

One thought on “Compile-time type identification

  1. Matt

    You are right, this is a pain and there should be a standard way of it.

    However, you can get closer to the ideal output.

    You can use template specialisation to name common types, e.g.


    template string TypeDecryptor::getName (void) { return "int"; }
    template string TypeDecryptor<MyClass >::getName (void) { return "MyClass"; }

    You can also add per-toolchain support for demangling, e.g.


    #if __GXX_ABI_VERSION > 1000
    #include
    template string TypeDecryptor::getName (void)
    {
    int s;
    char *b (abi::__cxa_demangle (typeid (T).name (), NULL, NULL, &s));
    //if (!b || s) throw ...;
    return b;
    }
    #else
    template string TypeDecryptor::getName (void) { return typeid (T).name (); }
    #endif

    boost::units::detail::demangle does pretty much this.

    Of course actually doing any of this is a pain in the ass.

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *