简体   繁体   中英

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

在c ++ 11中是否有一种标准方法可以使用某些模板黑魔法或使用某些标准库函数动态获取类的名称?

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

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, eg doubles. But it gives you also user defined types.

Not very fancy, but it has its uses.

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