Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Qt: typeid alternative

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?

like image 948
ragingbit Avatar asked Dec 19 '13 14:12

ragingbit


2 Answers

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

like image 103
lpapp Avatar answered Sep 20 '22 23:09

lpapp


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
like image 29
Kuba hasn't forgotten Monica Avatar answered Sep 17 '22 23:09

Kuba hasn't forgotten Monica