6

如果给我的类型的声明不包含Q_OBJECT宏,我有一些有趣的需要显示编译错误。我发现了一种不好的方法。实际上它重复了 Qt 开发人员的想法来做同样的伎俩:

template<typename T>
void checkForQObjectMacro()
{
    reinterpret_cast<T *>(0)->qt_check_for_QOBJECT_macro(*reinterpret_cast<T *>(0));
}

这很好用,但它确实给出了奇怪的错误消息。我想显示一条可读的消息。一种方法是使用static_assert构造。但我不知道如何实现Q_OBJECT宏存在的静态验证条件。也许有人可以提出一个漂亮的黑客?也非常感谢任何想法。

4

1 回答 1

4

这就是Qt 已经做到的方式:

Q_STATIC_ASSERT_X(QtPrivate::HasQ_OBJECT_Macro<typename SignalType::Object>::Value,
"No Q_OBJECT in the class with the signal");

请注意,它虽然从这里开始使用私有 API :

namespace QtPrivate {
    /* Trait that tells is a the Object has a Q_OBJECT macro */
    template <typename Object> struct HasQ_OBJECT_Macro {
        template <typename T>
        static char test(int (T::*)(QMetaObject::Call, int, void **));
        static int test(int (Object::*)(QMetaObject::Call, int, void **));
        enum { Value = sizeof(test(&Object::qt_metacall)) == sizeof(int) };
    };
}

在这里,您可以看到 Gerrit 5.2 中的变化:

https://codereview.qt-project.org/#change,65508

于 2014-01-13T21:41:13.893 回答