Add a helper for better error messages when functor is incompatible

Amends 207aae5560 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 <qt_ci_bot@qt-project.org>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
bb10
Volker Hilsheimer 2023-04-27 17:00:41 +02:00
parent 9958edba41
commit 1c5c1df43e
4 changed files with 19 additions and 8 deletions

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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;