summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/kernel/qobject.h20
-rw-r--r--tests/auto/corelib/kernel/qobject/tst_qobject.cpp36
2 files changed, 55 insertions, 1 deletions
diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h
index 689946b6c4..e9316c98f0 100644
--- a/src/corelib/kernel/qobject.h
+++ b/src/corelib/kernel/qobject.h
@@ -279,10 +279,28 @@ public:
static inline typename QtPrivate::QEnableIf<QtPrivate::FunctionPointer<Func2>::ArgumentCount == -1, QMetaObject::Connection>::Type
connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal, Func2 slot)
{
+#ifndef Q_COMPILER_DECLTYPE //Workaround the lack of decltype using another function as indirection
+ return connect_functor(sender, signal, slot, &Func2::operator()); }
+ template <typename Func1, typename Func2, typename Func2Operator>
+ static inline QMetaObject::Connection connect_functor(const QObject *sender, Func1 signal, Func2 slot, Func2Operator) {
+ typedef QtPrivate::FunctionPointer<Func2Operator> SlotType ;
+#else
+
+ typedef QtPrivate::FunctionPointer<decltype(&Func2::operator())> SlotType ;
+#endif
typedef QtPrivate::FunctionPointer<Func1> SignalType;
+ Q_STATIC_ASSERT_X(int(SignalType::ArgumentCount) >= int(SlotType::ArgumentCount),
+ "The slot requires more arguments than the signal provides.");
+ Q_STATIC_ASSERT_X((QtPrivate::CheckCompatibleArguments<typename SignalType::Arguments, typename SlotType::Arguments>::value),
+ "Signal and slot arguments are not compatible.");
+ Q_STATIC_ASSERT_X((QtPrivate::AreArgumentsCompatible<typename SlotType::ReturnType, typename SignalType::ReturnType>::value),
+ "Return type of the slot is not compatible with the return type of the signal.");
+
return connectImpl(sender, reinterpret_cast<void **>(&signal), sender, 0,
- new QtPrivate::QFunctorSlotObject<Func2, SignalType::ArgumentCount, typename SignalType::Arguments, typename SignalType::ReturnType>(slot),
+ new QtPrivate::QFunctorSlotObject<Func2, SlotType::ArgumentCount,
+ typename QtPrivate::List_Left<typename SignalType::Arguments, SlotType::ArgumentCount>::Value,
+ typename SignalType::ReturnType>(slot),
Qt::DirectConnection, 0, &SignalType::Object::staticMetaObject);
}
#endif //Q_QDOC
diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
index f48f86cceb..c340d00361 100644
--- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
+++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
@@ -140,6 +140,7 @@ private slots:
void returnValue2_data();
void returnValue2();
void connectVirtualSlots();
+ void connectFunctorArgDifference();
};
class SenderObject : public QObject
@@ -5484,5 +5485,40 @@ void tst_QObject::connectVirtualSlots()
*/
}
+struct SlotFunctor
+{
+ void operator()() {}
+};
+
+struct SlotFunctorString
+{
+ void operator()(const QString &) {}
+};
+
+void tst_QObject::connectFunctorArgDifference()
+{
+ QTimer timer;
+ // Compile-time tests that the connection is successful.
+ connect(&timer, &QTimer::timeout, SlotFunctor());
+ connect(&timer, &QTimer::objectNameChanged, SlotFunctorString());
+ connect(qApp, &QCoreApplication::aboutToQuit, SlotFunctor());
+
+ connect(&timer, &QTimer::objectNameChanged, SlotFunctor());
+ QStringListModel model;
+ connect(&model, &QStringListModel::rowsInserted, SlotFunctor());
+
+#if defined(Q_COMPILER_LAMBDA)
+ connect(&timer, &QTimer::timeout, [=](){});
+ connect(&timer, &QTimer::objectNameChanged, [=](const QString &){});
+ connect(qApp, &QCoreApplication::aboutToQuit, [=](){});
+
+ connect(&timer, &QTimer::objectNameChanged, [=](){});
+ connect(&model, &QStringListModel::rowsInserted, [=](){});
+ connect(&model, &QStringListModel::rowsInserted, [=](const QModelIndex &){});
+#endif
+
+ QVERIFY(true);
+}
+
QTEST_MAIN(tst_QObject)
#include "tst_qobject.moc"