typeid(T).name() alternative in c++11?

2019-05-04 15:20发布

问题:

Is there a standard way in c++11 to get the name of a class either with some template black magic or dynamically with some standard library function?

回答1:

Once I found the pretty printing of the function prototype quite useful:

In GCC, PRETTY_FUNCTION contains the type signature of the function as well as its bare name.

For example for a templated class or function you get the class names expanded as a C-string:

template<typename T>
class Vector {
  void foo(int i) {
    cout << __PRETTY_FUNCTION__ << endl;
  }
};

This would give you something like

void Vector<double>::foo(int)

If you had instantiated the class with, e.g. doubles. But it gives you also user defined types.

Not very fancy, but it has its uses.



回答2:

No, but you could make one:

template<class T> struct meta {
    static const std::string& get_name() {return T::class_name;}
};

and then either add the static member class_name to the class:

class MyClass {
public:
    static const std::string class_name("MyClass");
};

or specialize meta:

template<> struct meta<int> { 
    static const std::string class_name("int");
    static const std::string& get_name() {return class_name;}
};

(here's a macro to make that easier)

#define specialize_meta(name) template<>struct meta<name>{static const std::string class_name(#name); static const std::string& get_name() {return class_name;} };
specialize_meta(double);

and then use the meta template:

int main() {
   std::cout << meta<int>::get_name();
}

If you really want to get crafty, you can make a version for functions too, but these would (obviously) have to be specialized.

void foo(int) {} //function in question
template<class T, T& a> struct metafunc; //dont define generic.
template<decltype(foo), &foo> struct metafunc { //specialization
    static const std::string func_name("void foo(int)");
}