4

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?

ildjarn
  • 62,044
  • 9
  • 127
  • 211
Lorenzo Pistone
  • 5,028
  • 3
  • 34
  • 65
  • 1
    @spraff, the name representation is not standard though. – Lorenzo Pistone Jan 25 '12 at 15:29
  • Note that if you want to also have the CV qualifiers, you can use [this method](http://stackoverflow.com/a/20170989/1593077) due to @HowardHinnant . It's still based on `typeid(T).name()` though. – einpoklum Dec 22 '15 at 10:04

2 Answers2

8

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)");
}
Mooing Duck
  • 64,318
  • 19
  • 100
  • 158
  • 1
    If everything returned `std::string const&` instead of `std::string` there would be far fewer copies. :-] Also, `meta<>::get_name()` should be static. – ildjarn Jan 25 '12 at 18:49
  • @ildjarn: I had made them return copies so implimenters of `class_name` could assemble more complex strings in a full function rather than requiring it to be static `std::string` member. I couldn't' come up with a use-case however, so I went with your suggestion. – Mooing Duck Jan 25 '12 at 18:58
  • this requires some work on the target class. I cannot do that. – Lorenzo Pistone Jan 25 '12 at 18:58
  • 1
    @LorenzoPistone: No it doesn't. It's _easiest_ to modify the target class, but note that I also got it to work for `int`, which I obviously did not modify. Simply specialize the meta class. – Mooing Duck Jan 25 '12 at 19:14
  • @LorenzoPistone: Added a macro to make it _super_ easy to add specializations. – Mooing Duck Jan 27 '12 at 17:55
6

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.

ildjarn
  • 62,044
  • 9
  • 127
  • 211
ritter
  • 7,447
  • 7
  • 51
  • 84