在QGlobal.h中应用“sizeof”到不完全类型“QStaticAssertFailure”无效。

时间:2021-12-01 22:13:28

I am currently migrating a huge project from Qt 4.x to 5.2.1, Everything has been rather good until this error, which I find incredibly confusing because its located at the Qt files, and I believe the solution must be applied somewhere else, not in the qglobal.h located at 5.2.1\mingw48_32\include/QtCore/qglobal.h. The error must be happening somewhere else.

我正在从qt4迁移一个庞大的项目。x到5.2.1,在这个错误之前,一切都很好,我觉得非常混乱,因为它位于Qt文件中,我认为解决方案必须应用于其他地方,而不是qglobal。h位于5.2.1 \ mingw48_32 \包括/ QtCore / qglobal.h。错误必须发生在其他地方。

Heres the error:

这是错误的:

..........\Qt5\5.2.1\mingw48_32\include/QtCore/qglobal.h:681:85: error: invalid application of 'sizeof' to incomplete type 'QStaticAssertFailure' enum {Q_STATIC_ASSERT_PRIVATE_JOIN(q_static_assert_result, COUNTER) = sizeof(QStaticAssertFailure)} ^

.......... \ Qt5 \ 5.2.1 \ mingw48_32 \包括/ QtCore / qglobal。h:681:85:错误:将“sizeof”应用于不完全类型的QStaticAssertFailure' enum {Q_STATIC_ASSERT_PRIVATE_JOIN(q_static_assert_result, COUNTER) = sizeof(QStaticAssertFailure)}。

..........\Qt5\5.2.1\mingw48_32\include/QtCore/qglobal.h:686:47: note: in expansion of macro 'Q_STATIC_ASSERT' #define Q_STATIC_ASSERT_X(Condition, Message) Q_STATIC_ASSERT(Condition) ^

.......... \ 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\include/QtCore/qobject.h:520:5: note: in expansion of macro 'Q_STATIC_ASSERT_X' Q_STATIC_ASSERT_X(QtPrivate::HasQ_OBJECT_Macro::Value, ^

.......... \ Qt5 \ 5.2.1 \ mingw48_32 \包括/ QtCore / qobject。h:520:5:注意:在宏'Q_STATIC_ASSERT_X' Q_STATIC_ASSERT_X的扩展(QtPrivate::HasQ_OBJECT_Macro::Value,。

Here's the piece of code in qglobal.h

这是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

I have tried everything and have researched all about it, but didnt find a proper solution. I have wasted all day in this annoying piece of code. I hope someone can shed some light on the matter.

我已经试过了所有的方法,但都没有找到合适的解决方案。我在这恼人的代码中浪费了一整天。我希望有人能阐明这件事。

Thankyou very much.

非常谢谢。

EDIT: I searched for all the documents that included qglobal.h, but none of them make use of any assert funcion, so I dont know what could be triggering such error. Theres no way that the qglobal.h is wrong, so it must be something of the source code.

编辑:我搜索了所有包含qglobal的文档。h,但是他们都没有使用任何断言,所以我不知道是什么触发了这样的错误。qglobal是不可能的。h是错误的,所以它一定是源代码。

EDIT2: I managed to isolate the lines that trigger the error, apparently the compilation output gave more information than I thought, but it was so 'separated' that I thought it was a warning and had nothing to do. Here is the code from my application. The two commented lines are the ones that trigger the error. Sorry for my mistake.

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;
}

Its this part the one that causes the error:

它的这一部分导致了错误:

value<ISPSItem*>()

Heres the other part of the compilation error that I had ignored, in case it can help:

这是我忽略的编译错误的另一部分,如果它能提供帮助的话:

..........\Qt5\5.2.1\mingw48_32\include/QtCore/qobject.h: In instantiation of 'T qobject_cast(QObject*) [with T = ISPSItem*]': ..........\Qt5\5.2.1\mingw48_32\include/QtCore/qvariant.h:695:51: required from 'static T QtPrivate::QVariantValueHelper::object(const QVariant&) [with T = ISPSItem*]' ..........\Qt5\5.2.1\mingw48_32\include/QtCore/qvariant.h:101:37: required from 'static ReturnType QtPrivate::ObjectInvoker::invoke(Argument) [with Derived = QtPrivate::QVariantValueHelper; Argument = const QVariant&; ReturnType = ISPSItem*]' ..........\Qt5\5.2.1\mingw48_32\include/QtCore/qvariant.h:810:64: required from 'T qvariant_cast(const QVariant&) [with T = ISPSItem*]' ..........\Qt5\5.2.1\mingw48_32\include/QtCore/qvariant.h:348:36: required from 'T QVariant::value() const [with T = ISPSItem*]' ..\marssies\ispswidget.cpp:785:109: required from here EDIT3: I left those 2 lines commented and kept migrating the application, until I got the same error in another file, this is the line:

.......... \ Qt5 \ 5.2.1 \ mingw48_32 \包括/ QtCore / qobject。h:在实例化的“T qobject_cast(QObject*)[与T = ISPSItem*]”中:“”\Qt5\5.2.1\mingw48_32\包括/QtCore/qvariant。h:695:51: QVariantValueHelper::object(const qvariant&) [with T = ISPSItem*]'…\Qt5\5.2.1\mingw48_32\包括/QtCore/qvariant。h:101:37:要求从静态ReturnType QtPrivate::调用(参数)[与派生= QtPrivate::QVariantValueHelper;参数= const QVariant&;ReturnType = ISPSItem *]“.......... \ Qt5 \ 5.2.1 \ mingw48_32 \包括/ QtCore / qvariant。h:810:64:要求从T qvariant_cast(const qvariant&) [with 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:需要从这里编辑3:我离开了这两行注释并继续迁移应用程序,直到我在另一个文件中得到相同的错误,这是一行:

Im getting the same error in another .cpp using a different class, but what they have in common is the .value<Type>();

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

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

So definitely its the .value<Type>(); what throws the error, now the only thing left is to find a way around it.

因此,它的。value <类型> ();是什么导致了错误,现在唯一剩下的就是找到一种绕过它的方法。

Here is the object ISPSItem in case its useful:

这里有一个对象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 个解决方案

#1


6  

After getting much information about the error and the sources that trigger it I conclude, that the root cause could be in using QObject subclasses in QVariant, especially when calling QVariant::value() function. As Qt docs say:

在获得关于错误和触发它的源的大量信息之后,我得出结论,根本原因可能是在QVariant中使用QObject子类,特别是在调用QVariant::value()函数时。Qt文档说:

If the QVariant contains a pointer to a type derived from QObject then T may be any QObject type. If the pointer stored in the QVariant can be qobject_cast to T, then that result is returned. Otherwise a null pointer is returned. Note that this only works for QObject subclasses which use the Q_OBJECT macro.

如果QVariant包含一个指向来自QObject的类型的指针,那么T可能是任何QObject类型。如果在QVariant中存储的指针可以是qobject_cast到T,则返回该结果。否则将返回空指针。注意,这只适用于使用Q_OBJECT宏的QObject子类。

I believe, that adding Q_OBJECT macro to these classes (ISPSItem) declaration will solve the problem.

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

#2


2  

I see this problem when I change signals variable type but at the same time I forgot changing slots descriptions.For example; I have a signal slot : this is signal-> setResult(bool res); this is slot -> setResult(bool res){}

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

I change signal's type signal -> setResult(QString res); slot -> setResult(bool res); /////WHEN I FORGOT CHANGING THIS ASSERT THIS EXP

我改变信号的类型信号-> setResult(QString res);槽- > setResult(bool res);///// ///// ///// ///// ///// ///// ///// ///// //

#3


2  

Add this before you use ISPSItem as a QVariant cast:

在你使用ISPSItem作为一个q变体类型之前添加这个:

Q_DECLARE_METATYPE(ISPSItem)

To solve the problem you need to add your class to QMetaType, the macro do that.

要解决这个问题,您需要将类添加到QMetaType中,宏就会这样做。

Q_DECLARE_METATYPE(Type)

This macro makes the type Type known to QMetaType as long as it provides a public default constructor, a public copy constructor and a public destructor. It is needed to use the type Type as a custom type in QVariant.

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

Good look!

不错看!

#1


6  

After getting much information about the error and the sources that trigger it I conclude, that the root cause could be in using QObject subclasses in QVariant, especially when calling QVariant::value() function. As Qt docs say:

在获得关于错误和触发它的源的大量信息之后,我得出结论,根本原因可能是在QVariant中使用QObject子类,特别是在调用QVariant::value()函数时。Qt文档说:

If the QVariant contains a pointer to a type derived from QObject then T may be any QObject type. If the pointer stored in the QVariant can be qobject_cast to T, then that result is returned. Otherwise a null pointer is returned. Note that this only works for QObject subclasses which use the Q_OBJECT macro.

如果QVariant包含一个指向来自QObject的类型的指针,那么T可能是任何QObject类型。如果在QVariant中存储的指针可以是qobject_cast到T,则返回该结果。否则将返回空指针。注意,这只适用于使用Q_OBJECT宏的QObject子类。

I believe, that adding Q_OBJECT macro to these classes (ISPSItem) declaration will solve the problem.

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

#2


2  

I see this problem when I change signals variable type but at the same time I forgot changing slots descriptions.For example; I have a signal slot : this is signal-> setResult(bool res); this is slot -> setResult(bool res){}

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

I change signal's type signal -> setResult(QString res); slot -> setResult(bool res); /////WHEN I FORGOT CHANGING THIS ASSERT THIS EXP

我改变信号的类型信号-> setResult(QString res);槽- > setResult(bool res);///// ///// ///// ///// ///// ///// ///// ///// //

#3


2  

Add this before you use ISPSItem as a QVariant cast:

在你使用ISPSItem作为一个q变体类型之前添加这个:

Q_DECLARE_METATYPE(ISPSItem)

To solve the problem you need to add your class to QMetaType, the macro do that.

要解决这个问题,您需要将类添加到QMetaType中,宏就会这样做。

Q_DECLARE_METATYPE(Type)

This macro makes the type Type known to QMetaType as long as it provides a public default constructor, a public copy constructor and a public destructor. It is needed to use the type Type as a custom type in QVariant.

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

Good look!

不错看!