summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVolker Hilsheimer <[email protected]>2023-04-27 17:00:41 +0200
committerVolker Hilsheimer <[email protected]>2023-04-28 07:45:22 +0200
commit1c5c1df43e2be10c46c13461888b012c89938150 (patch)
treeff2ca1cf2bbbf15f6863eafead47e69f8ed32f8b
parent9958edba41ac49097a54e0872c3c4934d2dd81f9 (diff)
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 <[email protected]> Reviewed-by: Thiago Macieira <[email protected]>
-rw-r--r--src/corelib/kernel/qcoreapplication.h1
-rw-r--r--src/corelib/kernel/qobjectdefs_impl.h15
-rw-r--r--src/network/kernel/qhostinfo.h1
-rw-r--r--tests/auto/corelib/kernel/qobject/tst_qobject.cpp10
4 files changed, 19 insertions, 8 deletions
diff --git a/src/corelib/kernel/qcoreapplication.h b/src/corelib/kernel/qcoreapplication.h
index 2514c7630b7..ae01cdee9ae 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<Prototype, Functor>();
requestPermission(permission,
QtPrivate::makeSlotObject<Prototype>(std::forward<Functor>(func)),
receiver);
diff --git a/src/corelib/kernel/qobjectdefs_impl.h b/src/corelib/kernel/qobjectdefs_impl.h
index e8b9b4a2091..721193fe914 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<Functor>(func));
}
}
+
+ template<typename Prototype, typename Functor, typename = void>
+ struct AreFunctionsCompatible : std::false_type {};
+ template<typename Prototype, typename Functor>
+ struct AreFunctionsCompatible<Prototype, Functor, std::enable_if_t<
+ std::is_same_v<decltype(QtPrivate::makeSlotObject<Prototype>(std::forward<Functor>(std::declval<Functor>()))),
+ QtPrivate::QSlotObjectBase *>>
+ > : std::true_type {};
+
+ template<typename Prototype, typename Functor>
+ inline constexpr bool AssertCompatibleFunctions() {
+ static_assert(AreFunctionsCompatible<Prototype, Functor>::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 9b420bd3ca9..1f18bf83027 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<Prototype, Functor>();
return lookupHostImpl(name, receiver,
QtPrivate::makeSlotObject<Prototype>(std::forward<Functor>(func)),
nullptr);
diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
index 649f075a02e..76ceb842715 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<typename Functor>
bool callMe0(const typename QtPrivate::ContextTypeForFunctor<Functor>::ContextType *, Functor &&func)
{
+ QtPrivate::AssertCompatibleFunctions<Prototype0, Functor>();
auto *slotObject = QtPrivate::makeSlotObject<Prototype0>(std::forward<Functor>(func));
slotObject->destroyIfLastRef();
return true;
@@ -8391,6 +8392,7 @@ public:
template<typename Functor>
bool callMe1(const typename QtPrivate::ContextTypeForFunctor<Functor>::ContextType *, Functor &&func)
{
+ QtPrivate::AssertCompatibleFunctions<Prototype1, Functor>();
auto *slotObject = QtPrivate::makeSlotObject<Prototype1>(std::forward<Functor>(func));
slotObject->destroyIfLastRef();
return true;
@@ -8406,14 +8408,6 @@ public:
static void freeFunction0() {}
static void freeFunction1(QString) {}
-template<typename Prototype, typename Functor, typename = void>
-struct AreFunctionsCompatible : std::false_type {};
-template<typename Prototype, typename Functor>
-struct AreFunctionsCompatible<Prototype, Functor, std::enable_if_t<
- std::is_same_v<decltype(QtPrivate::makeSlotObject<Prototype>(std::forward<Functor>(std::declval<Functor>()))),
- QtPrivate::QSlotObjectBase *>>
-> : std::true_type {};
-
template<typename Prototype, typename Functor>
inline constexpr bool compiles(Functor &&) {
return QtPrivate::AreFunctionsCompatible<Prototype, Functor>::value;