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
Olivier Goffart 2015-04-23 12:02:40 +02:00 committed by Olivier Goffart (Woboq GmbH)
parent 63660402d8
commit 02f6b21bbc
4 changed files with 52 additions and 2 deletions

View File

@ -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

View File

@ -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()

View File

@ -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

View File

@ -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