我想知道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
有什么建议吗?
答案 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)
看起来你正试图获得通用变量,例如QVariant。
QVariant
适用于所有基本类型和所有Qt类型。其他类型可以是registered到qt元数据系统。