首页 > 解决方案 > Qt - 编译时检查 qRegisterMetaType() 被称为

问题描述

‎<br> 问题:有没有办法在编译时检查是否qRegisterMetaType<T>()调用了自定义类型T


自定义类型T需要在 Qt 元类型系统中注册才能用于例如排队连接。

如果建立了这样的连接并触发了信号,则会显示运行时警告:

QObject::connect: Cannot queue arguments of type 'T'
(Make sure 'T' is registered using qRegisterMetaType().)

这很难跟踪,所以我宁愿在编译时检查它。这有可能吗?

(我知道如果可能的话,它可能已经是 Qt 框架本身的一部分,但也许......?)


注意:我知道我可以检查一个类型是否被声明为元类型(检查类型是否被声明为元类型系统(对于 SFINAE)),但这并不能解决我的问题。


代码示例将是:

#include <QCoreApplication>
#include <QDebug>
#include <QMetaMethod>
#include <QObject>
#include <QThread>
#include <QTimer>


struct Payload {
    Payload() = default;
};
// Type is declared as metatype
Q_DECLARE_METATYPE(Payload) 


class ObjectOne : public QObject {
    Q_OBJECT
public:
    using QObject::QObject;
    void emitPayloadChanged() { Payload p; emit payloadChanged(p); }
signals:
    void payloadChanged(const Payload& p);
};


class ObjectTwo : public QObject {
    Q_OBJECT
public:
    using QObject::QObject;

    void handlePayload(const Payload& p) { qDebug() << "handling payload"; }
};


int main(int argc, char* argv[]) {
    QCoreApplication app(argc, argv);

    // Uncommenting the following line fixes the runtime warning
    // qRegisterMetaType<Payload>();  

    QThread t1, t2;

    ObjectOne o1;
    o1.moveToThread(&t1);

    ObjectTwo o2;
    o2.moveToThread(&t2);

    t1.start();
    t2.start();

    QObject::connect(&o1, &ObjectOne::payloadChanged, &o2, &ObjectTwo::handlePayload);

    QTimer::singleShot(0, &o1, [&] { QMetaObject::invokeMethod(&o1, &ObjectOne::emitPayloadChanged); });

    return app.exec();
}

#include "main.moc"

标签: qtqt5qobjectqmetaobject

解决方案


推荐阅读