From 1c5c1df43e2be10c46c13461888b012c89938150 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Thu, 27 Apr 2023 17:00:41 +0200 Subject: [PATCH] Add a helper for better error messages when functor is incompatible Amends 207aae5560aa2865ec55ddb9ecbb50048060c0c0 to make it easy to create human-friendly error messages. Since the functor-accepting member functions are not removed from the API, the first compile error will be that there is no suitable overload of the makeSlotObject helper, which. With the assert helper, the first error message is easier to understand. Change-Id: I4878ec35a44ddfa5dc9d9e358d81c3fd40389c0c Reviewed-by: Qt CI Bot Reviewed-by: Thiago Macieira --- src/corelib/kernel/qcoreapplication.h | 1 + src/corelib/kernel/qobjectdefs_impl.h | 15 +++++++++++++++ src/network/kernel/qhostinfo.h | 1 + tests/auto/corelib/kernel/qobject/tst_qobject.cpp | 10 ++-------- 4 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/corelib/kernel/qcoreapplication.h b/src/corelib/kernel/qcoreapplication.h index 2514c7630b..ae01cdee9a 100644 --- a/src/corelib/kernel/qcoreapplication.h +++ b/src/corelib/kernel/qcoreapplication.h @@ -126,6 +126,7 @@ public: Functor &&func) { using Prototype = void(*)(QPermission); + QtPrivate::AssertCompatibleFunctions(); requestPermission(permission, QtPrivate::makeSlotObject(std::forward(func)), receiver); diff --git a/src/corelib/kernel/qobjectdefs_impl.h b/src/corelib/kernel/qobjectdefs_impl.h index e8b9b4a209..721193fe91 100644 --- a/src/corelib/kernel/qobjectdefs_impl.h +++ b/src/corelib/kernel/qobjectdefs_impl.h @@ -512,6 +512,21 @@ namespace QtPrivate { ActualArguments, void>(std::forward(func)); } } + + template + struct AreFunctionsCompatible : std::false_type {}; + template + struct AreFunctionsCompatible(std::forward(std::declval()))), + QtPrivate::QSlotObjectBase *>> + > : std::true_type {}; + + template + inline constexpr bool AssertCompatibleFunctions() { + static_assert(AreFunctionsCompatible::value, + "Functor is not compatible with expected prototype!"); + return true; + } } QT_END_NAMESPACE diff --git a/src/network/kernel/qhostinfo.h b/src/network/kernel/qhostinfo.h index 9b420bd3ca..1f18bf8302 100644 --- a/src/network/kernel/qhostinfo.h +++ b/src/network/kernel/qhostinfo.h @@ -66,6 +66,7 @@ public: Functor &&func) { using Prototype = void(*)(QHostInfo); + QtPrivate::AssertCompatibleFunctions(); return lookupHostImpl(name, receiver, QtPrivate::makeSlotObject(std::forward(func)), nullptr); diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp index 649f075a02..76ceb84271 100644 --- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp +++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp @@ -8377,6 +8377,7 @@ public: template bool callMe0(const typename QtPrivate::ContextTypeForFunctor::ContextType *, Functor &&func) { + QtPrivate::AssertCompatibleFunctions(); auto *slotObject = QtPrivate::makeSlotObject(std::forward(func)); slotObject->destroyIfLastRef(); return true; @@ -8391,6 +8392,7 @@ public: template bool callMe1(const typename QtPrivate::ContextTypeForFunctor::ContextType *, Functor &&func) { + QtPrivate::AssertCompatibleFunctions(); auto *slotObject = QtPrivate::makeSlotObject(std::forward(func)); slotObject->destroyIfLastRef(); return true; @@ -8406,14 +8408,6 @@ public: static void freeFunction0() {} static void freeFunction1(QString) {} -template -struct AreFunctionsCompatible : std::false_type {}; -template -struct AreFunctionsCompatible(std::forward(std::declval()))), - QtPrivate::QSlotObjectBase *>> -> : std::true_type {}; - template inline constexpr bool compiles(Functor &&) { return QtPrivate::AreFunctionsCompatible::value;