在QGlobal.h上将'sizeof'无效应用于不完整类型'QStaticAssertFailure <false>'</false>

时间:2014-04-23 12:49:15

标签: c++ qt sizeof

我目前正在将一个巨大的项目从Qt 4.x迁移到5.2.1,一直都很好,直到这个错误,我发现它非常令人困惑,因为它位于Qt文件,我相信必须应用解决方案在其他地方,而不是位于5.2.1 \ mingw48_32 \ include / QtCore / qglobal.h的qglobal.h中。 错误必定发生在其他地方。

继承错误:

  

.......... \ Qt5 \ 5.2.1 \ mingw48_32 \ include / QtCore / qglobal.h :681:85:错误:无效的应用' sizeof'到不完整类型'QStaticAssertFailure'        枚举{Q_STATIC_ASSERT_PRIVATE_JOIN(q_static_assert_result, COUNTER )= sizeof(QStaticAssertFailure)}                                                                                        ^

     

.......... \ QT5 \ 5.2.1 \ mingw48_32 \包括/ QtCore / qglobal.h中:686:47:   注意:扩展宏'Q_STATIC_ASSERT'#define   Q_STATIC_ASSERT_X(条件,消息)Q_STATIC_ASSERT(条件)                                                  ^

     

.......... \ QT5 \ 5.2.1 \ mingw48_32 \包括/ QtCore / qobject.h:520:5:   注意:扩展宏'Q_STATIC_ASSERT_X'        Q_STATIC_ASSERT_X(QtPrivate :: HasQ_OBJECT_Macro ::值,        ^

这是qglobal.h中的一段代码

// Intentionally undefined
template <bool Test> class QStaticAssertFailure;
template <> class QStaticAssertFailure<true> {};

#define Q_STATIC_ASSERT_PRIVATE_JOIN(A, B) Q_STATIC_ASSERT_PRIVATE_JOIN_IMPL(A, B)
#define Q_STATIC_ASSERT_PRIVATE_JOIN_IMPL(A, B) A ## B
#ifdef __COUNTER__
#define Q_STATIC_ASSERT(Condition) \
    enum {Q_STATIC_ASSERT_PRIVATE_JOIN(q_static_assert_result, __COUNTER__) = sizeof(QStaticAssertFailure<!!(Condition)>)}
#else
#define Q_STATIC_ASSERT(Condition) \
    enum {Q_STATIC_ASSERT_PRIVATE_JOIN(q_static_assert_result, __LINE__) = sizeof(QStaticAssertFailure<!!(Condition)>)}
#endif /* __COUNTER__ */
#define Q_STATIC_ASSERT_X(Condition, Message) Q_STATIC_ASSERT(Condition)
#endif

我已经尝试了所有的东西并且已经研究了所有这些,但没有找到合适的解决方案。我整天浪费在这段恼人的代码中。我希望有人能够对此事有所了解。

非常感谢。

编辑:我搜索了包含qglobal.h的所有文档,但没有一个使用任何断言函数,所以我不知道什么可能触发这样的错误。没有办法qglobal.h是错的,所以它必须是源代码的东西。

EDIT2:我设法隔离了触发错误的行,显然编译输出提供了比我想象的更多的信息,但它是如此“分开”,我认为这是一个警告,无所事事。这是我的应用程序的代码。两条注释行是触发错误的行。抱歉我的错误。

bool ISPSModel::removeGraphics(GraphicsPrimitive* _gtr) {

    for (int _i = 0; _i < ispss.size(); _i++) {

        for (int _j = 0; _j < ispss[_i]->graphicsObjects.size(); _j++) {

            if (ispss[_i]->graphicsObjects[_j] != _gtr)
                continue;

            if (ispss[_i]->graphicsObjects.contains(_gtr)) {

                //beginRemoveRows(indexFromItem(ispss[_i]->m_item), _gtr->getData(DATA_ROLE).value<ISPSItem*>()->row(), _gtr->getData(DATA_ROLE).value<ISPSItem*>()->row());
               //_gtr->getData(DATA_ROLE).value<ISPSItem*>()->remove();
                ispss[_i]->removeGraphics(ispss[_i]->graphicsObjects[_j]);
                endRemoveRows();
                return true;
            }
        }
    }

    return false;
}

这部分导致错误:

value<ISPSItem*>()

下面是我忽略的编译错误的另一部分,以防它可以提供帮助:

  

.......... \ Qt5 \ 5.2.1 \ mingw48_32 \ include / QtCore / qobject.h:In   实例化'T qobject_cast(QObject *)[with T = ISPSItem *]':   .......... \ QT5 \ 5.2.1 \ mingw48_32 \包括/ QtCore / qvariant.h:695:51:   需要'静态T   QtPrivate :: QVariantValueHelper :: object(const QVariant&amp;)[with T =   ISPSItem *]”   .......... \ QT5 \ 5.2.1 \ mingw48_32 \包括/ QtCore / qvariant.h:101:37:   'static ReturnType QtPrivate :: ObjectInvoker :: invoke(Argument)[with Derived =   QtPrivate :: QVariantValueHelper; Argument = const QVariant&amp ;;   ReturnType = ISPSItem *]'   .......... \ QT5 \ 5.2.1 \ mingw48_32 \包括/ QtCore / qvariant.h:810:64:   需要'T qvariant_cast(const QVariant&amp;)[与T = ISPSItem *]'   .......... \ QT5 \ 5.2.1 \ mingw48_32 \包括/ QtCore / qvariant.h:348:36:   来自'T QVariant :: value()const [with T = ISPSItem *]'   .. \ marssies \ ispswidget.cpp:785:109:从这里需要   EDIT3:   我留下了那两行注释并继续迁移应用程序,直到我在另一个文件中得到相同的错误,这就是这一行:

我在另一个.cpp中使用不同的类获得相同的错误,但它们的共同点是.value<Type>();

Notify* _n = ui.notifyBox->model()->data(index, Qt::UserRole).value<Notify*>();

所以肯定是.value<Type>();会引发错误,现在唯一剩下的就是找到解决方法。

这是ISPSItem的对象,如果它有用:

class ISPSItem : public QObject {

public:
    enum Level {ROOT_LEVEL = 1,
                    ISPS_LEVEL,
                        GRAPHICS_LEVEL
                    } level;

    ISPSItem(ISPSItem* = NULL, Level = ROOT_LEVEL, int = -1);
    ~ISPSItem();

    ISPSItem* parentItem() {return _parentItem;}

    ISPSItem* child(int);
    void appendChild(ISPSItem*);
    void insertChild(ISPSItem*, int);
    int childCount() const {return children.size();}

    int row() const;
    int newNodeRow(Level);
    void remove();

private:
    QList<ISPSItem*> children;
    ISPSItem* _parentItem;
    void remove(ISPSItem*);
};
Q_DECLARE_METATYPE(ISPSItem*)

3 个答案:

答案 0 :(得分:7)

在获得有关错误的大量信息以及触发它的源代码后,我得出结论,根本原因可能是在QVariant中使用QObject子类,尤其是在调用QVariant::value()函数时。正如Qt博士所说:

  

如果QVariant包含指向从QObject派生的类型的指针,那么   T可以是任何QObject类型。如果存储在QVariant中的指针可以   将qobject_cast改为T,然后返回该结果。否则为null   返回指针。 请注意,这仅适用于QObject子类   它使用Q_OBJECT宏

我相信,将Q_OBJECT宏添加到这些类(ISPSItem)声明将解决问题。

答案 1 :(得分:2)

当我更改信号变量类型时我看到了这个问题,但同时我忘了更改插槽描述。例如; 我有一个信号槽:这是信号 - &gt; setResult(bool res);                         这是插槽 - &gt; setResult(bool res){}

我改变信号的类型信号 - &gt; setResult(QString res);                         插槽 - &gt; setResult( bool res ); ///// 当我忘记更改此评估此

答案 2 :(得分:2)

在将ISPSItem用作QVariant转换之前添加此项:

Q_DECLARE_METATYPE(ISPSItem)

要解决问题,您需要将类添加到QMetaType,宏就可以。

Q_DECLARE_METATYPE(Type)

只要它提供了一个公共默认构造函数,一个公共复制构造函数和一个公共析构函数,这个宏就会使QMetaType知道类型Type。需要在QVariant中使用Type类型作为自定义类型。

好看!