Qt: typeid alternative

4.9k views Asked by At

I'm wondering if Qt provides an alternative to typeid to recognize variable types and get their name in a human-readable format. My specific problem is the following:

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

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

the idea would be that of generalizing a variable to use as a input to functions. As a side node tyeinfo seems not to be working correctly on my system (I'm using MinGW on Windows 7), if I try:

  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 get

i
7QString
d
f

Any suggestion?

3

There are 3 answers

0
László Papp On BEST ANSWER

You could use this:

const char * QVariant::typeName () const

Returns the name of the type stored in the variant. The returned strings describe the C++ datatype used to store the data: for example, "QFont", "QString", or "QVariantList". An Invalid variant returns 0.

This will work for POD and registered built-in Qt types. You would need to use the following method for register your custom type though.

int qRegisterMetaType(const char * typeName)

One another thing you could try, although it is somewhat superfluous to QVariant is to work with Object's QMetaObject in the following way:

const char * QMetaObject::className() const

Returns the class name.

and

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

Returns a pointer to the meta-object of this object.

A meta-object contains information about a class that inherits QObject, e.g. class name, superclass name, properties, signals and slots. Every QObject subclass that contains the Q_OBJECT macro will have a meta-object.

The meta-object information is required by the signal/slot connection mechanism and the property system. The inherits() function also makes use of the meta-object.

If you have no pointer to an actual object instance but still want to access the meta-object of a class, you can use staticMetaObject.

Needless to say, this will only work for QObjects, so not for QString, etc. You would need to create QObject subclasses.

There is also some QMetaType that you can use for creation, but this is a bit different, so I am just mentioning here to be complete:

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

Returns a handle to the type called typeName, or QMetaType::UnknownType if there is no such type.

Here you can find all the types:

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

0
Kuba hasn't forgotten Monica On

You are getting mangled type names. That's perfectly fine, as the behavior is implementation is defined. To get it human-readable, you need to demangle the names on the compilers that do mangle the names (gcc and llvm).

The below works under g++, llvm-c++, and MS Visual C++, so it's about as portable as one can reasonably expect.

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

Output from gcc and LLVM:

int
QEvent
MyEvent

Output from MSVC:

int
class QEvent
class MyEvent
0
Marek R On

It looks like that you are trying to get universal variable, something like QVariant. QVariant works perfectly for all basic types and all Qt types. Other types can be registered to qt meta data system.