可读形式的typeid?

时间:2012-07-29 12:59:56

标签: c++ c++11 typeid

是否有编译器以可读的方式返回类型的名称(或提供该功能或工具的库)。基本上我想要的是与您在源代码中编写的类型表达式相对应的字符串。

4 个答案:

答案 0 :(得分:3)

 typeid(var).name()

正是您要找的。输出的编译器与编译器的输出不同......例如,对于gccint的输出为iunsigned的输出为j。这是一个小测试程序:

#include <iostream>
#include <typeinfo>

struct A { virtual ~A() { } };
struct B : A { };

class C { };
class D : public C { };

int main() {
  B b;
  A* ap = &b;
  A& ar = b;
  std::cout << "ap: " << typeid(*ap).name() << std::endl;
  std::cout << "ar: " << typeid(ar).name() << std::endl;

  D d;
  C* cp = &d;
  C& cr = d;
  std::cout << "cp: " << typeid(*cp).name() << std::endl;
  std::cout << "cr: " << typeid(cr).name() << std::endl;

  int e;
  unsigned f;
  char g;
  float h;
  double i;
  std::cout << "int:\t" << typeid(e).name() << std::endl;
  std::cout << "unsigned:\t" << typeid(f).name() << std::endl;
  std::cout << "char:\t" << typeid(g).name() << std::endl;
  std::cout << "float:\t" << typeid(h).name() << std::endl;
  std::cout << "double:\t" << typeid(i).name() << std::endl;
}

另请参阅此问题:typeid(T).name() alternative in c++11?

答案 1 :(得分:2)

在搜索此问题时,我刚刚在boost库中找到了我需要的东西: boost::core::demangle

在我的情况下,这是为了捕获异常:

try {
  //...
} catch (std::exception& e) {
  boost::core::scoped_demangled_name demangled(typeid(e).name());
  std::cerr << "ERROR: " << demangled.get() << ": " << e.what() << std::endl;
}

答案 2 :(得分:0)

下面是我写来检查类型的小类。您可以根据需要添加更多类型。它无法检查数组类型,映射或任何过于先进的内容。您可以根据需要添加更多类型,甚至可以添加自己的自定义类型。这只是一个小样本。

此外,您正在寻找getType函数。根据匹配的类型,您可以自定义输出字符串。我省略了包含部分,因此您只需找到合适的包含文件,因为该库是我较大的库的一部分。

/ * header.hpp * /

class _cType
{
    public:
    _cType();
    ~_cType();

    template<class T, class U>
    static bool isSame(T &vl, U &vr);

    template<class T>
    static bool isInt(T &v);

    template<class T>
    static bool isUInt(T &v);           

    template<class T>
    static bool isFloat(T &v);

    template<class T>
    static bool isLong(T &v);

    template<class T>
    static bool isDouble(T &v);

    template<class T>
    static bool isBool(T &v);

    template<class T>
    static bool isString(T &v);

    template<class T>
    static bool isChar(T &v);

    template<class T>
    static std::string getType(T &v);

};

extern _cType Type;

/ * source.cpp * /

_cType::_cType(){};


template<class T, class U>
bool _cType::isSame(T &vl, U &vr){
    return ( typeid(vl) == typeid(vr) );
}

template<class T>
bool _cType::isInt(T &v){
    return typeid(v) == typeid(int);
}

template<class T>
bool _cType::isUInt(T &v){
    return typeid(v) == typeid(unsigned int);
}    

template<class T>
bool _cType::isFloat(T &v){
    return typeid(v) == typeid(float);
}

template<class T>
bool _cType::isLong(T &v){
    return typeid(v) == typeid(long);
}

template<class T>
bool _cType::isDouble(T &v){
    return typeid(v) == typeid(double);
}

template<class T>
bool _cType::isBool(T &v){
    return typeid(v) == typeid(bool);
}

template<class T>
bool _cType::isString(T &v){
    return typeid(v) == typeid(std::string);
}

template<class T>
bool _cType::isChar(T &v){
    return typeid(v) == typeid(char);
}

template<class T>
std::string _cType::getType(T &v){

    if ( typeid(v) == typeid(int) ) return "int";    
    else if ( typeid(v) == typeid(unsigned int) ) return "unsigned int";
    else if ( typeid(v) == typeid(float) ) return "float";
    else if ( typeid(v) == typeid(long) ) return "long";
    else if ( typeid(v) == typeid(double) ) return "double";
    else if ( typeid(v) == typeid(char) ) return "char";
    else if ( typeid(v) == typeid(std::string) ) return "std::string";
    else if ( typeid(v) == typeid(bool) ) return "bool";
    else return std::string("User defined or unknown type: ") + typeid(v).name();
}

_cType::~_cType(){};

_cType Type;

答案 3 :(得分:0)

要回答您的问题的字母(其他答案都可以解决问题的意图),最简单的答案是Visual C ++为std::type_info::name()提供“未修饰的”(未修饰的)名称作为输出,同时隐藏实际的名称,编译器扩展std::type_info::raw_name()后面的错误类型; CPPReference还提到IBM和Oracle提供了易于理解的名称,但是我对它们的编译器没有经验,因此我自己不能说这种说法是否正确。