Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting type names at compile time in C++ [duplicate]

I want to get the type name and print it for debug purposes. I use the following code:

#include <cxxabi.h>

inline const char* demangle(const char *s) {
    abi::__cxa_demangle(s, 0, 0, NULL);
}

template<typename T>
inline const char* type_name() {
    return demangle(typeid(T).name());
}

It works well, but it I suppose there is an unnecessary runtime overhead. Is there any way to get a human-readable form of type ids that is computed at compile time? I am thinking of something that looks like this:

boost::mpl::type_name<MyType>::value

Which would return a string constant of the type name.

like image 635
petersohn Avatar asked Sep 19 '11 10:09

petersohn


4 Answers

I can't see typeid(T).name() incurring a runtime overhead. typeid(expr) yes, if expr is of a polymorphic type.

It looks like the demangling probably happens at runtime, but there's not an awful lot you can do about that. If this is only for debugging then I really wouldn't worry about it too much unless your profiler indicates that this is causing your program to slow down so much that debugging other elements of it is troublesome.

like image 127
Lightness Races in Orbit Avatar answered Nov 15 '22 01:11

Lightness Races in Orbit


I have the same need, I've solved it using the _____FUNCTION_____ maccro in a static method of my class. But you must do some runtine computation on _____FUNCTION_____ to extract the class name. You have to do some template tricks to avoid paste the same code in every class. If someone is interessed I may clean and translate my code from french  to post it.

The main advantage of this method is that you don't need to enable RRTI. On the other hand, the extraction of the class name may be compiler dependant.

template <class MyT>
    class NamedClass
    {
        static std::string ComputeClassName()
        {
            std::string funcMacro=__FUNCTION__;
//compiler dependant
            static const std::string start="scul::NamedClass<class ";
            static const std::string end=">::ComputeClassName";

            return funcMacro.substr(start.size(),funcMacro.size()-end.size()-start.size());;
        }
        static const std::string _ClassName;

    };

    template <class MyT>
    const std::string NamedClass<MyT>::_ClassName=NamedClass<MyT>::ComputeClassName();
like image 3
Fericelli Avatar answered Nov 15 '22 01:11

Fericelli


You could use std::type_index to cache the demangled strings.

like image 1
spraff Avatar answered Nov 15 '22 01:11

spraff


You could use an std::map or similar data structure (splay trees for example) to cache and access the demangled name relatively quickly. It's not done in compile time though, I doubt the latter is possible.

like image 1
Frigo Avatar answered Nov 15 '22 01:11

Frigo