QMetaType: Fix compilation with non default constructible Q_GADGET
Do not try to automatically register the meta type for Q_GADGET that are not default constructible. This fixes a source incompatibility in the function pointer syntax of QObject::connect when such types are used as an argument of a signal. Task-number: QTBUG-45721 Change-Id: I3065f6d57bc1f37e16988d2dee99118de250ca56 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>bb10
parent
63660402d8
commit
02f6b21bbc
|
|
@ -506,6 +506,27 @@ Q_STATIC_ASSERT((!is_unsigned<qint64>::value));
|
|||
Q_STATIC_ASSERT((!is_signed<quint64>::value));
|
||||
Q_STATIC_ASSERT(( is_signed<qint64>::value));
|
||||
|
||||
template<class T = void> struct is_default_constructible;
|
||||
|
||||
template<> struct is_default_constructible<void>
|
||||
{
|
||||
protected:
|
||||
template<bool> struct test { typedef char type; };
|
||||
public:
|
||||
static bool const value = false;
|
||||
};
|
||||
template<> struct is_default_constructible<>::test<true> { typedef double type; };
|
||||
|
||||
template<class T> struct is_default_constructible : is_default_constructible<>
|
||||
{
|
||||
private:
|
||||
template<class U> static typename test<!!sizeof(::new U())>::type sfinae(U*);
|
||||
template<class U> static char sfinae(...);
|
||||
public:
|
||||
static bool const value = sizeof(sfinae<T>(0)) > 1;
|
||||
};
|
||||
|
||||
|
||||
} // namespace QtPrivate
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -1773,7 +1773,7 @@ template <typename T>
|
|||
struct QMetaTypeIdQObject<T, QMetaType::IsGadget>
|
||||
{
|
||||
enum {
|
||||
Defined = 1
|
||||
Defined = QtPrivate::is_default_constructible<T>::value
|
||||
};
|
||||
|
||||
static int qt_metatype_id()
|
||||
|
|
|
|||
|
|
@ -142,6 +142,11 @@ public:
|
|||
class CustomGadget {
|
||||
Q_GADGET
|
||||
};
|
||||
class CustomGadget_NonDefaultConstructible {
|
||||
Q_GADGET
|
||||
public:
|
||||
CustomGadget_NonDefaultConstructible(int) {};
|
||||
};
|
||||
|
||||
class CustomNonQObject {};
|
||||
class GadgetDerived : public CustomGadget {};
|
||||
|
|
@ -159,7 +164,7 @@ void tst_QMetaType::defined()
|
|||
QVERIFY(!QMetaTypeId2<CustomQObject>::Defined);
|
||||
QVERIFY(!QMetaTypeId2<CustomNonQObject>::Defined);
|
||||
QVERIFY(!QMetaTypeId2<CustomNonQObject*>::Defined);
|
||||
QVERIFY(!QMetaTypeId2<CustomGadget*>::Defined);
|
||||
QVERIFY(!QMetaTypeId2<CustomGadget_NonDefaultConstructible>::Defined);
|
||||
}
|
||||
|
||||
struct Bar
|
||||
|
|
|
|||
|
|
@ -128,6 +128,7 @@ private slots:
|
|||
void connectWithReference();
|
||||
void connectManyArguments();
|
||||
void connectForwardDeclare();
|
||||
void connectNoDefaultConstructorArg();
|
||||
void returnValue_data();
|
||||
void returnValue();
|
||||
void returnValue2_data();
|
||||
|
|
@ -5227,6 +5228,29 @@ void tst_QObject::connectForwardDeclare()
|
|||
QVERIFY(connect(&ob, &ForwardDeclareArguments::mySignal, &ob, &ForwardDeclareArguments::mySlot, Qt::QueuedConnection));
|
||||
}
|
||||
|
||||
class NoDefaultConstructor
|
||||
{
|
||||
Q_GADGET
|
||||
public:
|
||||
NoDefaultConstructor(int) {}
|
||||
};
|
||||
|
||||
class NoDefaultContructorArguments : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
signals:
|
||||
void mySignal(const NoDefaultConstructor&);
|
||||
public slots:
|
||||
void mySlot(const NoDefaultConstructor&) {}
|
||||
};
|
||||
|
||||
void tst_QObject::connectNoDefaultConstructorArg()
|
||||
{
|
||||
NoDefaultContructorArguments ob;
|
||||
// it should compile
|
||||
QVERIFY(connect(&ob, &NoDefaultContructorArguments::mySignal, &ob, &NoDefaultContructorArguments::mySlot, Qt::QueuedConnection));
|
||||
}
|
||||
|
||||
class ReturnValue : public QObject {
|
||||
friend class tst_QObject;
|
||||
Q_OBJECT
|
||||
|
|
|
|||
Loading…
Reference in New Issue