summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/kernel/qobject.h4
-rw-r--r--src/corelib/kernel/qobjectdefs_impl.h2
-rw-r--r--tests/auto/corelib/kernel/qobject/tst_qobject.cpp42
3 files changed, 45 insertions, 3 deletions
diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h
index 6941c55896..2e66daa914 100644
--- a/src/corelib/kernel/qobject.h
+++ b/src/corelib/kernel/qobject.h
@@ -304,7 +304,7 @@ public:
static inline typename std::enable_if<QtPrivate::FunctionPointer<Func2>::ArgumentCount == -1, QMetaObject::Connection>::type
connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal, Func2 slot)
{
- return connect(sender, signal, sender, slot, Qt::DirectConnection);
+ return connect(sender, signal, sender, std::move(slot), Qt::DirectConnection);
}
//connect to a functor, with a "context" object defining in which event loop is going to be executed
@@ -334,7 +334,7 @@ public:
return connectImpl(sender, reinterpret_cast<void **>(&signal), context, Q_NULLPTR,
new QtPrivate::QFunctorSlotObject<Func2, SlotArgumentCount,
typename QtPrivate::List_Left<typename SignalType::Arguments, SlotArgumentCount>::Value,
- typename SignalType::ReturnType>(slot),
+ typename SignalType::ReturnType>(std::move(slot)),
type, types, &SignalType::Object::staticMetaObject);
}
#endif //Q_QDOC
diff --git a/src/corelib/kernel/qobjectdefs_impl.h b/src/corelib/kernel/qobjectdefs_impl.h
index ef68050529..876742ab6c 100644
--- a/src/corelib/kernel/qobjectdefs_impl.h
+++ b/src/corelib/kernel/qobjectdefs_impl.h
@@ -430,7 +430,7 @@ namespace QtPrivate {
}
}
public:
- explicit QFunctorSlotObject(const Func &f) : QSlotObjectBase(&impl), function(f) {}
+ explicit QFunctorSlotObject(Func f) : QSlotObjectBase(&impl), function(std::move(f)) {}
};
// typedefs for readability for when there are no parameters
diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
index db6bdf0809..89d6be6c7a 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 connectFunctorWithContext();
void connectFunctorWithContextUnique();
void connectFunctorDeadlock();
+ void connectFunctorMoveOnly();
void connectStaticSlotWithObject();
void disconnectDoesNotLeakFunctor();
void contextDoesNotLeakFunctor();
@@ -6237,6 +6238,47 @@ void tst_QObject::connectFunctorDeadlock()
sender.emitSignal1();
}
+void tst_QObject::connectFunctorMoveOnly()
+{
+ struct MoveOnlyFunctor {
+ Q_DISABLE_COPY(MoveOnlyFunctor)
+ MoveOnlyFunctor(int *status) : status(status) {}
+ MoveOnlyFunctor(MoveOnlyFunctor &&o) : status(o.status) { o.status = nullptr; };
+ void operator()(int i) { *status = i; }
+ void operator()() { *status = -8; }
+ int *status;
+ };
+
+ int status = 1;
+ SenderObject obj;
+ QEventLoop e;
+
+ connect(&obj, &SenderObject::signal1, MoveOnlyFunctor(&status));
+ QCOMPARE(status, 1);
+ obj.signal1();
+ QCOMPARE(status, -8);
+
+ connect(&obj, &SenderObject::signal7, MoveOnlyFunctor(&status));
+ QCOMPARE(status, -8);
+ obj.signal7(7888, "Hello");
+ QCOMPARE(status, 7888);
+
+ // With a context
+ status = 1;
+ connect(&obj, &SenderObject::signal2, this, MoveOnlyFunctor(&status));
+ QCOMPARE(status, 1);
+ obj.signal2();
+ QCOMPARE(status, -8);
+
+ // QueuedConnection
+ status = 1;
+ connect(&obj, &SenderObject::signal3, this, MoveOnlyFunctor(&status), Qt::QueuedConnection);
+ obj.signal3();
+ QCOMPARE(status, 1);
+ QCoreApplication::processEvents();
+ QCOMPARE(status, -8);
+}
+
static int s_static_slot_checker = 1;
class StaticSlotChecker : public QObject