Qt:typeid备选方案

Qt: typeid alternative

本文关键字:方案 typeid Qt      更新时间:2023-10-16

我想知道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似乎在我的系统上无法正常工作(我在Windows7上使用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

有什么建议吗?

您可以使用这个:

const char * QVariant::typeName () const

返回存储在变体中的类型的名称。返回的字符串描述用于存储数据的C++数据类型:例如;QFont"QString";,或";QVariantList";。Invalid变量返回0。

这将适用于POD和注册的内置Qt类型。不过,您需要使用以下方法来注册您的自定义类型。

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可以用于创建,但这有点不同,所以我只是在这里提到完整的:

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

返回名为typeName的类型的句柄,如果没有此类类型,则返回QMetaType::UnknowType。

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

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

您得到了损坏的类型名称。这很好,因为行为就是实现是定义的。为了使其具有可读性,您需要在编译器上对名称(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

看起来您正在尝试获取通用变量,比如QVariant。QVariant适用于所有基本类型和所有Qt类型。其他类型可以注册到qt元数据系统。