Qt:typeid替代品

时间:2013-12-19 14:50:08

标签: c++ qt qtcore typeinfo

我想知道Qt是否提供了typeid的替代方法来识别变量类型并以人类可读的格式获取它们的名称。 我的具体问题如下:

struct gArgument{
    QString type; 
    void* arg;
};

void gargConverter(gArgument* oArg, T data){
    oArg->type = typeid(data).name();
    oArg->arg = static_cast<void*> (&data);
}

这个想法是概括一个变量用作函数的输入。 作为一个侧节点tyeinfo似乎在我的系统上没有正常工作(我在Windows 7上使用MinGW),如果我尝试:

  int i; std::cout <<   typeid(i).name() << std::endl;
  QString s; std::cout <<   typeid(s).name() << std::endl;
  double d; std::cout <<   typeid(d).name() << std::endl;
  float f; std::cout <<   typeid(f).name() << std::endl;

我得到了

i
7QString
d
f

有什么建议吗?

3 个答案:

答案 0 :(得分:4)

您可以使用this

  

const char * QVariant::typeName () const

     

返回变体中存储的类型的名称。返回的字符串描述用于存储数据的C ++数据类型:例如,“QFont”,“QString”或“QVariantList”。无效变量返回0.

这适用于POD和已注册的内置Qt类型。您需要使用following method注册您的自定义类型。

int qRegisterMetaType(const char * typeName)

你可以尝试另外一件事,虽然QVariant有点多余,但是以下列方式使用Object的QMetaObject:

  

const char * QMetaObject::className() const

     

返回类名。

  

const QMetaObject * QObject::metaObject() const [virtual]

     

返回指向此对象的元对象的指针。

     

元对象包含有关继承QObject的类的信息,例如:类名,超类名,属性,信号和插槽。包含Q_OBJECT宏的每个QObject子类都将有一个元对象。

     

信号/插槽连接机制和属性系统需要元对象信息。 inherits()函数也使用了元对象。

     

如果没有指向实际对象实例的指针但仍希望访问类的元对象,则可以使用staticMetaObject。

毋庸置疑,这只适用于QObjects,因此不适用于QString等。您需要创建QObject子类。

您还可以使用一些QMetaType进行创建,但this有点不同,所以我只是提到这里是完整的:

  

int QMetaType::type(const char * typeName) [static]

     

返回名为typeName的类型的句柄,如果没有这样的类型,则返回QMetaType :: UnknownType。

在这里您可以找到所有类型:

http://qt-project.org/doc/qt-5.1/qtcore/qmetatype.html#Type-enum

答案 1 :(得分:1)

你正在获得受损的类型名称。这很好,因为行为是实现定义。为了使它具有人类可读性,您需要对编译器上的名称进行解码(gcc和llvm)。

下面的内容适用于g ++,llvm-c ++和MS Visual C ++,因此它可以像人们合理预期的那样便携。

#include <iostream>
#ifndef _MSC_VER
#include <cxxabi.h>
#endif

struct QEvent { virtual ~QEvent() {} };

struct MyEvent : public QEvent {};

#ifndef _MSC_VER
template <typename T> void dumpType(T val)
{
  int status;
  char * realname = abi::__cxa_demangle(typeid(val).name(), 0, 0, &status);
  std::cout << realname << std::endl;
  free(realname); //important!
}

template <typename T> void dumpType(T *ptr)
{
  int status;
  char * realname = abi::__cxa_demangle(typeid(*ptr).name(), 0, 0, &status);
  std::cout << realname << std::endl;
  free(realname); //important!
}
#else
template <typename T> void dumpType(T val)
{
  std::cout << typeid(val).name() << std::endl;
}
template <typename T> void dumpType(T *ptr)
{
  std::cout << typeid(*ptr).name() << std::endl;
}
#endif

int main() {
  QEvent * base = new QEvent;
  QEvent * der = new MyEvent;
  dumpType(int());
  dumpType(base);
  dumpType(der);
}

gcc和LLVM的输出:

int
QEvent
MyEvent

MSVC的输出:

int
class QEvent
class MyEvent

答案 2 :(得分:0)

看起来你正试图获得通用变量,例如QVariantQVariant适用于所有基本类型和所有Qt类型。其他类型可以是registered到qt元数据系统。