Вопрос: Есть ли способ проверить во время компиляции, был ли вызван qRegisterMetaType<T>()
для пользовательского типа T
?
Пользовательский тип T
должен быть зарегистрирован в системе мета-типов Qt для использования, например, в соединениях с очередями.
Если такое соединение установлено и сработал сигнал, будет показано предупреждение времени выполнения:
QObject::connect: Cannot queue arguments of type 'T'
(Make sure 'T' is registered using qRegisterMetaType().)
Это сложно отследить, поэтому я бы предпочел проверить это во время компиляции. Это каким-либо образом возможно?
(я понимаю, что, если бы это было возможно, оно, вероятно, уже было бы частью самой Qt Framework, но, возможно, ...?)
Примечание: я знаю, что могу проверить если тип был объявлен как метатип ( Проверьте, объявлен ли тип как система мета-типов (для 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"