diff --git a/src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp b/src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp
index ccf8399e0d4..ba02f75963c 100644
--- a/src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp
+++ b/src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp
@@ -568,6 +568,29 @@ struct A : public B {
template<> class QTypeInfo : public QTypeInfoMerger {};
//! [51]
+//! [52]
+ struct Foo {
+ void overloadedFunction();
+ void overloadedFunction(int, QString);
+ };
+ ... qOverload<>(&Foo:overloadedFunction)
+ ... qOverload(&Foo:overloadedFunction)
+//! [52]
+
+//! [53]
+ ... QOverload<>::of(&Foo:overloadedFunction)
+ ... QOverload::of(&Foo:overloadedFunction)
+//! [53]
+
+//! [54]
+ struct Foo {
+ void overloadedFunction(int, QString);
+ void overloadedFunction(int, QString) const;
+ };
+ ... qConstOverload<>(&Foo:overloadedFunction)
+ ... qNonConstOverload(&Foo:overloadedFunction)
+//! [54]
+
//! [qlikely]
// the condition inside the "if" will be successful most of the times
for (int i = 1; i <= 365; i++) {
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp
index a7ed29d8591..e4fa0f73918 100644
--- a/src/corelib/global/qglobal.cpp
+++ b/src/corelib/global/qglobal.cpp
@@ -921,6 +921,49 @@ Q_STATIC_ASSERT_X(QT_POINTER_SIZE == sizeof(void *), "QT_POINTER_SIZE defined in
\sa qMin(), qMax()
*/
+/*! \fn auto qOverload(T functionPointer)
+ \relates
+ \since 5.7
+
+ qOverload() returns a pointer to an overloaded function. The template
+ parameter is the list of the argument types of the function.
+ \a functionPointer is the pointer to the (member) function:
+
+ \snippet code/src_corelib_global_qglobal.cpp 52
+
+ If a member function is also const-overladed \l qConstOverload and
+ \l qNonConstOverload needs to be used.
+
+ qOverload() needs C++14 enabled. In C++11 only code the helper
+ classes QOverload, QConstOverload, and QNonConstOverload could be used directly:
+
+ \snippet code/src_corelib_global_qglobal.cpp 53
+
+ \sa qConstOverload(), qNonConstOverload()
+*/
+
+/*! \fn auto qConstOverload(T memberFunctionPointer)
+ \relates
+ \since 5.7
+
+ qConstOverload() returns a pointer to an constant member function:
+
+ \snippet code/src_corelib_global_qglobal.cpp 54
+
+ \sa qOverload, qNonConstOverload
+*/
+
+/*! \fn auto qNonConstOverload(T memberFunctionPointer)
+ \relates
+ \since 5.7
+
+ qNonConstOverload() eturns a pointer to an non constant member function:
+
+ \snippet code/src_corelib_global_qglobal.cpp 54
+
+ \sa qOverload, qNonConstOverload
+*/
+
/*!
\macro QT_VERSION_CHECK
\relates
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h
index 69840996dc3..d607b04192b 100644
--- a/src/corelib/global/qglobal.h
+++ b/src/corelib/global/qglobal.h
@@ -1018,6 +1018,66 @@ Q_CORE_EXPORT QString qtTrId(const char *id, int n = -1);
{ return T::dynamic_cast_will_always_fail_because_rtti_is_disabled; }
#endif
+
+#ifdef Q_QDOC
+
+// Just for documentation generation
+auto qOverload(T functionPointer);
+auto qConstOverload(T memberFunctionPointer);
+auto qNonConstOverload(T memberFunctionPointer);
+
+#elif defined(Q_COMPILER_VARIADIC_TEMPLATES)
+
+template
+struct QNonConstOverload
+{
+ template
+ Q_DECL_CONSTEXPR auto operator()(R (T::*ptr)(Args...)) const Q_DECL_NOTHROW -> decltype(ptr)
+ { return ptr; }
+
+ template
+ static Q_DECL_CONSTEXPR auto of(R (T::*ptr)(Args...)) Q_DECL_NOTHROW -> decltype(ptr)
+ { return ptr; }
+};
+
+template
+struct QConstOverload
+{
+ template
+ Q_DECL_CONSTEXPR auto operator()(R (T::*ptr)(Args...) const) const Q_DECL_NOTHROW -> decltype(ptr)
+ { return ptr; }
+
+ template
+ static Q_DECL_CONSTEXPR auto of(R (T::*ptr)(Args...) const) Q_DECL_NOTHROW -> decltype(ptr)
+ { return ptr; }
+};
+
+template
+struct QOverload : QConstOverload, QNonConstOverload
+{
+ using QConstOverload::of;
+ using QConstOverload::operator();
+ using QNonConstOverload::of;
+ using QNonConstOverload::operator();
+
+ template
+ Q_DECL_CONSTEXPR auto operator()(R (*ptr)(Args...)) const Q_DECL_NOTHROW -> decltype(ptr)
+ { return ptr; }
+
+ template
+ static Q_DECL_CONSTEXPR auto of(R (*ptr)(Args...)) Q_DECL_NOTHROW -> decltype(ptr)
+ { return ptr; }
+};
+
+#if defined(__cpp_variable_templates) && __cpp_variable_templates >= 201304 // C++14
+template Q_CONSTEXPR QOverload qOverload Q_DECL_UNUSED = {};
+template Q_CONSTEXPR QConstOverload qConstOverload Q_DECL_UNUSED = {};
+template Q_CONSTEXPR QNonConstOverload qNonConstOverload Q_DECL_UNUSED = {};
+#endif
+
+#endif
+
+
class QByteArray;
Q_CORE_EXPORT QByteArray qgetenv(const char *varName);
Q_CORE_EXPORT bool qputenv(const char *varName, const QByteArray& value);
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index dea8c200ef0..6702f78a04f 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -4538,6 +4538,8 @@ void qDeleteInEventHandler(QObject *o)
make sure to declare the argument type with Q_DECLARE_METATYPE
+ Overloaded functions can be resolved with help of \l qOverload.
+
\note The number of arguments in the signal or slot are limited to 6 if
the compiler does not support C++11 variadic templates.
*/
@@ -4573,6 +4575,8 @@ void qDeleteInEventHandler(QObject *o)
However, you should take care that any objects used within the functor
are still alive when the signal is emitted.
+ Overloaded functions can be resolved with help of \l qOverload.
+
\note If the compiler does not support C++11 variadic templates, the number
of arguments in the signal or slot are limited to 6, and the functor object
must not have an overloaded or templated operator().
@@ -4612,6 +4616,8 @@ void qDeleteInEventHandler(QObject *o)
However, you should take care that any objects used within the functor
are still alive when the signal is emitted.
+ Overloaded functions can be resolved with help of \l qOverload.
+
\note If the compiler does not support C++11 variadic templates, the number
of arguments in the signal or slot are limited to 6, and the functor object
must not have an overloaded or templated operator().
diff --git a/tests/auto/corelib/global/qglobal/tst_qglobal.cpp b/tests/auto/corelib/global/qglobal/tst_qglobal.cpp
index d1a6e662034..152906287c3 100644
--- a/tests/auto/corelib/global/qglobal/tst_qglobal.cpp
+++ b/tests/auto/corelib/global/qglobal/tst_qglobal.cpp
@@ -55,6 +55,7 @@ private slots:
void qprintable();
void qprintable_data();
void buildAbiEndianness();
+ void testqOverload();
};
void tst_QGlobal::qIsNull()
@@ -652,5 +653,126 @@ void tst_QGlobal::buildAbiEndianness()
QVERIFY(QSysInfo::buildAbi().contains(endian));
}
+struct Overloaded
+{
+ void foo() {}
+ void foo(QByteArray) {}
+ void foo(QByteArray, const QString &) {}
+
+ void constFoo() const {}
+ void constFoo(QByteArray) const {}
+ void constFoo(QByteArray, const QString &) const {}
+
+ void mixedFoo() {}
+ void mixedFoo(QByteArray) const {}
+};
+
+void freeOverloaded() {}
+void freeOverloaded(QByteArray) {}
+void freeOverloaded(QByteArray, const QString &) {}
+
+void freeOverloadedGet(QByteArray) {}
+QByteArray freeOverloadedGet() { return QByteArray(); }
+
+
+void tst_QGlobal::testqOverload()
+{
+#ifdef Q_COMPILER_VARIADIC_TEMPLATES
+
+ // void returning free overloaded functions
+ QVERIFY(QOverload<>::of(&freeOverloaded) ==
+ static_cast(&freeOverloaded));
+
+ QVERIFY(QOverload::of(&freeOverloaded) ==
+ static_cast(&freeOverloaded));
+
+ QVERIFY((QOverload::of(&freeOverloaded)) ==
+ static_cast(&freeOverloaded));
+
+ // value returning free overloaded functions
+ QVERIFY(QOverload<>::of(&freeOverloadedGet) ==
+ static_cast(&freeOverloadedGet));
+
+ QVERIFY(QOverload::of(&freeOverloadedGet) ==
+ static_cast(&freeOverloadedGet));
+
+ // void returning overloaded member functions
+ QVERIFY(QOverload<>::of(&Overloaded::foo) ==
+ static_cast(&Overloaded::foo));
+
+ QVERIFY(QOverload::of(&Overloaded::foo) ==
+ static_cast(&Overloaded::foo));
+
+ QVERIFY((QOverload::of(&Overloaded::foo)) ==
+ static_cast(&Overloaded::foo));
+
+ // void returning overloaded const member functions
+ QVERIFY(QOverload<>::of(&Overloaded::constFoo) ==
+ static_cast(&Overloaded::constFoo));
+
+ QVERIFY(QOverload::of(&Overloaded::constFoo) ==
+ static_cast(&Overloaded::constFoo));
+
+ QVERIFY((QOverload::of(&Overloaded::constFoo)) ==
+ static_cast(&Overloaded::constFoo));
+
+ // void returning overloaded const AND non-const member functions
+ QVERIFY(QNonConstOverload<>::of(&Overloaded::mixedFoo) ==
+ static_cast(&Overloaded::mixedFoo));
+
+ QVERIFY(QConstOverload::of(&Overloaded::mixedFoo) ==
+ static_cast(&Overloaded::mixedFoo));
+
+#if defined(__cpp_variable_templates) && __cpp_variable_templates >= 201304 // C++14
+
+ // void returning free overloaded functions
+ QVERIFY(qOverload<>(&freeOverloaded) ==
+ static_cast(&freeOverloaded));
+
+ QVERIFY(qOverload(&freeOverloaded) ==
+ static_cast(&freeOverloaded));
+
+ QVERIFY((qOverload(&freeOverloaded)),
+ static_cast(&freeOverloaded));
+
+ // value returning free overloaded functions
+ QVERIFY(qOverload<>(&freeOverloadedGet) ==
+ static_cast(&freeOverloadedGet));
+
+ QVERIFY(qOverload(&freeOverloadedGet) ==
+ static_cast(&freeOverloadedGet));
+
+ // void returning overloaded member functions
+ QVERIFY(qOverload<>(&Overloaded::foo) ==
+ static_cast(&Overloaded::foo));
+
+ QVERIFY(qOverload(&Overloaded::foo) ==
+ static_cast(&Overloaded::foo));
+
+ QVERIFY((qOverload(&Overloaded::foo)) ==
+ static_cast(&Overloaded::foo));
+
+ // void returning overloaded const member functions
+ QVERIFY(qOverload<>(&Overloaded::constFoo) ==
+ static_cast(&Overloaded::constFoo));
+
+ QVERIFY(qOverload(&Overloaded::constFoo) ==
+ static_cast(&Overloaded::constFoo));
+
+ QVERIFY((qOverload(&Overloaded::constFoo)) ==
+ static_cast(&Overloaded::constFoo));
+
+ // void returning overloaded const AND non-const member functions
+ QVERIFY(qNonConstOverload<>(&Overloaded::mixedFoo) ==
+ static_cast(&Overloaded::mixedFoo));
+
+ QVERIFY(qConstOverload(&Overloaded::mixedFoo) ==
+ static_cast(&Overloaded::mixedFoo));
+#endif
+
+#endif
+}
+
+
QTEST_APPLESS_MAIN(tst_QGlobal)
#include "tst_qglobal.moc"