diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h index 539818ac1d..c119fdfe7e 100644 --- a/src/corelib/kernel/qobject_p.h +++ b/src/corelib/kernel/qobject_p.h @@ -467,10 +467,35 @@ inline void QObjectPrivate::disconnectNotify(const QMetaMethod &signal) } namespace QtPrivate { -template class QPrivateSlotObject : public QSlotObjectBase + +template +struct FunctionStorageByValue +{ + Func f; + Func &func() noexcept { return f; } +}; + +template +struct FunctionStorageEmptyBaseClassOptimization : Func +{ + Func &func() noexcept { return *this; } + using Func::Func; +}; + +template +using FunctionStorage = typename std::conditional_t< + std::conjunction_v< + std::is_empty, + std::negation> + >, + FunctionStorageEmptyBaseClassOptimization, + FunctionStorageByValue + >; + +template +class QPrivateSlotObject : public QSlotObjectBase, private FunctionStorage { typedef QtPrivate::FunctionPointer FuncType; - Func function; static void impl(int which, QSlotObjectBase *this_, QObject *r, void **a, bool *ret) { switch (which) { @@ -478,17 +503,17 @@ template class QPrivateSlotObject : pu delete static_cast(this_); break; case Call: - FuncType::template call(static_cast(this_)->function, + FuncType::template call(static_cast(this_)->func(), static_cast(QObjectPrivate::get(r)), a); break; case Compare: - *ret = *reinterpret_cast(a) == static_cast(this_)->function; + *ret = *reinterpret_cast(a) == static_cast(this_)->func(); break; case NumOperations: ; } } public: - explicit QPrivateSlotObject(Func f) : QSlotObjectBase(&impl), function(f) {} + explicit QPrivateSlotObject(Func f) : QSlotObjectBase(&impl), FunctionStorage{std::move(f)} {} }; } //namespace QtPrivate diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp index 3d52478299..599f690ab2 100644 --- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp +++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp @@ -5221,7 +5221,7 @@ namespace ManyArgumentNamespace { } }; - struct Funct6 { + struct Funct6 final { void operator()(const QString &a, const QString &b, const QString &c, const QString&d, const QString&e, const QString&f) { MANYARGUMENT_COMPARE(a); MANYARGUMENT_COMPARE(b); MANYARGUMENT_COMPARE(c); MANYARGUMENT_COMPARE(d); MANYARGUMENT_COMPARE(e); MANYARGUMENT_COMPARE(f);