diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h index dbe5fc02a49..22572c072e2 100644 --- a/src/corelib/kernel/qobject.h +++ b/src/corelib/kernel/qobject.h @@ -212,7 +212,12 @@ public: reinterpret_cast(0)->qt_check_for_QOBJECT_macro(*reinterpret_cast(0)); //compilation error if the arguments does not match. - typedef typename QtPrivate::CheckCompatibleArguments::IncompatibleSignalSlotArguments EnsureCompatibleArguments; + Q_STATIC_ASSERT_X(int(SignalType::ArgumentCount) >= int(SlotType::ArgumentCount), + "The slot requires more arguments than the signal provides."); + Q_STATIC_ASSERT_X((QtPrivate::CheckCompatibleArguments::value), + "Signal and slot arguments are not compatible."); + Q_STATIC_ASSERT_X((QtPrivate::AreArgumentsCompatible::value), + "Return type of the slot is not compatible with the return type of the signal."); const int *types = 0; if (type == Qt::QueuedConnection || type == Qt::BlockingQueuedConnection) @@ -234,8 +239,12 @@ public: typedef QtPrivate::FunctionPointer SlotType; //compilation error if the arguments does not match. - typedef typename QtPrivate::CheckCompatibleArguments::IncompatibleSignalSlotArguments EnsureCompatibleArguments; - typedef typename QtPrivate::QEnableIf<(int(SignalType::ArgumentCount) >= int(SlotType::ArgumentCount))>::Type EnsureArgumentsCount; + Q_STATIC_ASSERT_X(int(SignalType::ArgumentCount) >= int(SlotType::ArgumentCount), + "The slot requires more arguments than the signal provides."); + Q_STATIC_ASSERT_X((QtPrivate::CheckCompatibleArguments::value), + "Signal and slot arguments are not compatible."); + Q_STATIC_ASSERT_X((QtPrivate::AreArgumentsCompatible::value), + "Return type of the slot is not compatible with the return type of the signal."); return connectImpl(sender, reinterpret_cast(&signal), sender, 0, new QStaticSlotObject(0)->qt_check_for_QOBJECT_macro(*reinterpret_cast(0)); //compilation error if the arguments does not match. - typedef typename QtPrivate::CheckCompatibleArguments::IncompatibleSignalSlotArguments EnsureCompatibleArguments; + Q_STATIC_ASSERT_X((QtPrivate::CheckCompatibleArguments::value), + "Signal and slot arguments are not compatible."); + return disconnectImpl(sender, reinterpret_cast(&signal), receiver, reinterpret_cast(&slot), &SignalType::Object::staticMetaObject); } diff --git a/src/corelib/kernel/qobject_impl.h b/src/corelib/kernel/qobject_impl.h index 660294b9564..1ddc95fc44a 100644 --- a/src/corelib/kernel/qobject_impl.h +++ b/src/corelib/kernel/qobject_impl.h @@ -441,36 +441,40 @@ namespace QtPrivate { /* Logic that check if the arguments of the slot matches the argument of the signal. To be used like this: - CheckCompatibleArguments::Arguments, FunctionPointer::Arguments>::IncompatibleSignalSlotArguments - The IncompatibleSignalSlotArguments type do not exist if the argument are incompatible and can - then produce error message. + Q_STATIC_ASSERT(CheckCompatibleArguments::Arguments, FunctionPointer::Arguments>::value) */ - template struct CheckCompatibleArgumentsHelper {}; - template struct CheckCompatibleArgumentsHelper : T {}; template struct AreArgumentsCompatible { static int test(A2); static char test(...); - static A2 dummy(); + static A1 dummy(); enum { value = sizeof(test(dummy())) == sizeof(int) }; }; template struct AreArgumentsCompatible { enum { value = false }; }; template struct AreArgumentsCompatible { enum { value = true }; }; + // void as a return value + template struct AreArgumentsCompatible { enum { value = true }; }; + template struct AreArgumentsCompatible { enum { value = true }; }; + template<> struct AreArgumentsCompatible { enum { value = true }; }; #ifndef Q_COMPILER_VARIADIC_TEMPLATES - template struct CheckCompatibleArguments{}; - template <> struct CheckCompatibleArguments { typedef bool IncompatibleSignalSlotArguments; }; - template struct CheckCompatibleArguments { typedef bool IncompatibleSignalSlotArguments; }; + template struct CheckCompatibleArguments { enum { value = false }; }; + template <> struct CheckCompatibleArguments { enum { value = true }; }; + template struct CheckCompatibleArguments { enum { value = true }; }; template struct CheckCompatibleArguments, List > - : CheckCompatibleArgumentsHelper, AreArgumentsCompatible< - typename RemoveConstRef::Type, typename RemoveConstRef::Type>::value > {}; + { + enum { value = AreArgumentsCompatible::Type, typename RemoveConstRef::Type>::value + && CheckCompatibleArguments::value }; + }; #else - template struct CheckCompatibleArguments{}; - template <> struct CheckCompatibleArguments, List<>> { typedef bool IncompatibleSignalSlotArguments; }; - template struct CheckCompatibleArguments> { typedef bool IncompatibleSignalSlotArguments; }; + template struct CheckCompatibleArguments { enum { value = false }; }; + template <> struct CheckCompatibleArguments, List<>> { enum { value = true }; }; + template struct CheckCompatibleArguments> { enum { value = true }; }; template struct CheckCompatibleArguments, List> - : CheckCompatibleArgumentsHelper, List>, AreArgumentsCompatible< - typename RemoveConstRef::Type, typename RemoveConstRef::Type>::value > {}; + { + enum { value = AreArgumentsCompatible::Type, typename RemoveConstRef::Type>::value + && CheckCompatibleArguments, List>::value }; + }; #endif