Qt:typeid备选方案
Qt: typeid alternative
我想知道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元数据系统。
- 运行同一解决方案的另一个项目的项目
- Project Euler问题4的错误解决方案
- 计算每个节点的树高,帮助我解释这个代码解决方案
- C++:Application.cpp中抛出了未解析的外部符号(解决方案在问题的末尾,供未来的读者参考)
- visual c++,如何获取解决方案目录中的代码
- C++typeid模板值转换为联合不可接受的转换
- 使用typeid警告未使用的变量
- 有没有办法在远程设备上打开和编辑visual Studio 2017解决方案
- C++Matching Brackets 2解决方案不起作用
- 在 ubuntu3 上C++ goto 定义有什么解决方案吗16.04?
- C++11 中不同类型的对象的 std::array 的替代方案
- 在 leetcode 上提交解决方案时出现堆栈缓冲区溢出错误
- 别名模板的专业化 C++11 中没有开销的最佳替代方案
- 我的固定时间步长与增量时间和插值的解决方案是错误的吗?
- 无法在问题解决方案中执行输出逻辑
- 最大的回文产品 - 程序未运行,编写解决方案但无法理解问题
- 从预序遍历构造 bst 的 c++ 和 python 解决方案之间的区别
- Qt:typeid备选方案
- 什么时候使用"typeid"是最好的解决方案?
- typeid()面向对象设计备选方案