c ++ 11中的typeid(T).name()替代?

时间:2012-01-25 14:45:26

标签: c++ reflection c++11

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

2 个答案:

答案 0 :(得分:7)

不,但你可以制作一个:

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

然后将静态成员class_name添加到类:

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

或专门化meta:

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

(这是一个让这更容易的宏)

#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);

然后使用元模板:

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

如果真的想要变得狡猾,你也可以为函数创建一个版本,但这些(显然)必须是专门的。

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

答案 1 :(得分:5)

一旦我发现函数原型的漂亮打印非常有用:

在GCC中, PRETTY_FUNCTION 包含函数的类型签名及其裸名称。

例如,对于模板化的类或函数,您可以将类名扩展为C字符串:

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

这会给你类似的东西

void Vector<double>::foo(int)

如果您已使用例如实例化该类,例如双打。但它也为您提供了用户定义的类型。

不是很花哨,但它有其用途。