Add qOverload to select overloaded functions
[ChangeLog][QtCore][Global] qOverload added to select overloaded functions. Change-Id: I7c9b1b054e6631eca0b5594db59e1202ef552c33 Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>
This commit is contained in:
parent
e41e034669
commit
ab8cc8387f
@ -568,6 +568,29 @@ struct A : public B {
|
|||||||
template<> class QTypeInfo<A> : public QTypeInfoMerger<A, B, C, D> {};
|
template<> class QTypeInfo<A> : public QTypeInfoMerger<A, B, C, D> {};
|
||||||
//! [51]
|
//! [51]
|
||||||
|
|
||||||
|
//! [52]
|
||||||
|
struct Foo {
|
||||||
|
void overloadedFunction();
|
||||||
|
void overloadedFunction(int, QString);
|
||||||
|
};
|
||||||
|
... qOverload<>(&Foo:overloadedFunction)
|
||||||
|
... qOverload<int, QString>(&Foo:overloadedFunction)
|
||||||
|
//! [52]
|
||||||
|
|
||||||
|
//! [53]
|
||||||
|
... QOverload<>::of(&Foo:overloadedFunction)
|
||||||
|
... QOverload<int, QString>::of(&Foo:overloadedFunction)
|
||||||
|
//! [53]
|
||||||
|
|
||||||
|
//! [54]
|
||||||
|
struct Foo {
|
||||||
|
void overloadedFunction(int, QString);
|
||||||
|
void overloadedFunction(int, QString) const;
|
||||||
|
};
|
||||||
|
... qConstOverload<>(&Foo:overloadedFunction)
|
||||||
|
... qNonConstOverload<int, QString>(&Foo:overloadedFunction)
|
||||||
|
//! [54]
|
||||||
|
|
||||||
//! [qlikely]
|
//! [qlikely]
|
||||||
// the condition inside the "if" will be successful most of the times
|
// the condition inside the "if" will be successful most of the times
|
||||||
for (int i = 1; i <= 365; i++) {
|
for (int i = 1; i <= 365; i++) {
|
||||||
|
@ -921,6 +921,49 @@ Q_STATIC_ASSERT_X(QT_POINTER_SIZE == sizeof(void *), "QT_POINTER_SIZE defined in
|
|||||||
\sa qMin(), qMax()
|
\sa qMin(), qMax()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*! \fn auto qOverload(T functionPointer)
|
||||||
|
\relates <QtGlobal>
|
||||||
|
\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 <QtGlobal>
|
||||||
|
\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 <QtGlobal>
|
||||||
|
\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
|
\macro QT_VERSION_CHECK
|
||||||
\relates <QtGlobal>
|
\relates <QtGlobal>
|
||||||
|
@ -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; }
|
{ return T::dynamic_cast_will_always_fail_because_rtti_is_disabled; }
|
||||||
#endif
|
#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 <typename... Args>
|
||||||
|
struct QNonConstOverload
|
||||||
|
{
|
||||||
|
template <typename R, typename T>
|
||||||
|
Q_DECL_CONSTEXPR auto operator()(R (T::*ptr)(Args...)) const Q_DECL_NOTHROW -> decltype(ptr)
|
||||||
|
{ return ptr; }
|
||||||
|
|
||||||
|
template <typename R, typename T>
|
||||||
|
static Q_DECL_CONSTEXPR auto of(R (T::*ptr)(Args...)) Q_DECL_NOTHROW -> decltype(ptr)
|
||||||
|
{ return ptr; }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename... Args>
|
||||||
|
struct QConstOverload
|
||||||
|
{
|
||||||
|
template <typename R, typename T>
|
||||||
|
Q_DECL_CONSTEXPR auto operator()(R (T::*ptr)(Args...) const) const Q_DECL_NOTHROW -> decltype(ptr)
|
||||||
|
{ return ptr; }
|
||||||
|
|
||||||
|
template <typename R, typename T>
|
||||||
|
static Q_DECL_CONSTEXPR auto of(R (T::*ptr)(Args...) const) Q_DECL_NOTHROW -> decltype(ptr)
|
||||||
|
{ return ptr; }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename... Args>
|
||||||
|
struct QOverload : QConstOverload<Args...>, QNonConstOverload<Args...>
|
||||||
|
{
|
||||||
|
using QConstOverload<Args...>::of;
|
||||||
|
using QConstOverload<Args...>::operator();
|
||||||
|
using QNonConstOverload<Args...>::of;
|
||||||
|
using QNonConstOverload<Args...>::operator();
|
||||||
|
|
||||||
|
template <typename R>
|
||||||
|
Q_DECL_CONSTEXPR auto operator()(R (*ptr)(Args...)) const Q_DECL_NOTHROW -> decltype(ptr)
|
||||||
|
{ return ptr; }
|
||||||
|
|
||||||
|
template <typename R>
|
||||||
|
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 <typename... Args> Q_CONSTEXPR QOverload<Args...> qOverload Q_DECL_UNUSED = {};
|
||||||
|
template <typename... Args> Q_CONSTEXPR QConstOverload<Args...> qConstOverload Q_DECL_UNUSED = {};
|
||||||
|
template <typename... Args> Q_CONSTEXPR QNonConstOverload<Args...> qNonConstOverload Q_DECL_UNUSED = {};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
class QByteArray;
|
class QByteArray;
|
||||||
Q_CORE_EXPORT QByteArray qgetenv(const char *varName);
|
Q_CORE_EXPORT QByteArray qgetenv(const char *varName);
|
||||||
Q_CORE_EXPORT bool qputenv(const char *varName, const QByteArray& value);
|
Q_CORE_EXPORT bool qputenv(const char *varName, const QByteArray& value);
|
||||||
|
@ -4538,6 +4538,8 @@ void qDeleteInEventHandler(QObject *o)
|
|||||||
|
|
||||||
make sure to declare the argument type with Q_DECLARE_METATYPE
|
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
|
\note The number of arguments in the signal or slot are limited to 6 if
|
||||||
the compiler does not support C++11 variadic templates.
|
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
|
However, you should take care that any objects used within the functor
|
||||||
are still alive when the signal is emitted.
|
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
|
\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
|
of arguments in the signal or slot are limited to 6, and the functor object
|
||||||
must not have an overloaded or templated operator().
|
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
|
However, you should take care that any objects used within the functor
|
||||||
are still alive when the signal is emitted.
|
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
|
\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
|
of arguments in the signal or slot are limited to 6, and the functor object
|
||||||
must not have an overloaded or templated operator().
|
must not have an overloaded or templated operator().
|
||||||
|
@ -55,6 +55,7 @@ private slots:
|
|||||||
void qprintable();
|
void qprintable();
|
||||||
void qprintable_data();
|
void qprintable_data();
|
||||||
void buildAbiEndianness();
|
void buildAbiEndianness();
|
||||||
|
void testqOverload();
|
||||||
};
|
};
|
||||||
|
|
||||||
void tst_QGlobal::qIsNull()
|
void tst_QGlobal::qIsNull()
|
||||||
@ -652,5 +653,126 @@ void tst_QGlobal::buildAbiEndianness()
|
|||||||
QVERIFY(QSysInfo::buildAbi().contains(endian));
|
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<void (*)()>(&freeOverloaded));
|
||||||
|
|
||||||
|
QVERIFY(QOverload<QByteArray>::of(&freeOverloaded) ==
|
||||||
|
static_cast<void (*)(QByteArray)>(&freeOverloaded));
|
||||||
|
|
||||||
|
QVERIFY((QOverload<QByteArray, const QString &>::of(&freeOverloaded)) ==
|
||||||
|
static_cast<void (*)(QByteArray, const QString &)>(&freeOverloaded));
|
||||||
|
|
||||||
|
// value returning free overloaded functions
|
||||||
|
QVERIFY(QOverload<>::of(&freeOverloadedGet) ==
|
||||||
|
static_cast<QByteArray (*)()>(&freeOverloadedGet));
|
||||||
|
|
||||||
|
QVERIFY(QOverload<QByteArray>::of(&freeOverloadedGet) ==
|
||||||
|
static_cast<void (*)(QByteArray)>(&freeOverloadedGet));
|
||||||
|
|
||||||
|
// void returning overloaded member functions
|
||||||
|
QVERIFY(QOverload<>::of(&Overloaded::foo) ==
|
||||||
|
static_cast<void (Overloaded::*)()>(&Overloaded::foo));
|
||||||
|
|
||||||
|
QVERIFY(QOverload<QByteArray>::of(&Overloaded::foo) ==
|
||||||
|
static_cast<void (Overloaded::*)(QByteArray)>(&Overloaded::foo));
|
||||||
|
|
||||||
|
QVERIFY((QOverload<QByteArray, const QString &>::of(&Overloaded::foo)) ==
|
||||||
|
static_cast<void (Overloaded::*)(QByteArray, const QString &)>(&Overloaded::foo));
|
||||||
|
|
||||||
|
// void returning overloaded const member functions
|
||||||
|
QVERIFY(QOverload<>::of(&Overloaded::constFoo) ==
|
||||||
|
static_cast<void (Overloaded::*)() const>(&Overloaded::constFoo));
|
||||||
|
|
||||||
|
QVERIFY(QOverload<QByteArray>::of(&Overloaded::constFoo) ==
|
||||||
|
static_cast<void (Overloaded::*)(QByteArray) const>(&Overloaded::constFoo));
|
||||||
|
|
||||||
|
QVERIFY((QOverload<QByteArray, const QString &>::of(&Overloaded::constFoo)) ==
|
||||||
|
static_cast<void (Overloaded::*)(QByteArray, const QString &) const>(&Overloaded::constFoo));
|
||||||
|
|
||||||
|
// void returning overloaded const AND non-const member functions
|
||||||
|
QVERIFY(QNonConstOverload<>::of(&Overloaded::mixedFoo) ==
|
||||||
|
static_cast<void (Overloaded::*)()>(&Overloaded::mixedFoo));
|
||||||
|
|
||||||
|
QVERIFY(QConstOverload<QByteArray>::of(&Overloaded::mixedFoo) ==
|
||||||
|
static_cast<void (Overloaded::*)(QByteArray) const>(&Overloaded::mixedFoo));
|
||||||
|
|
||||||
|
#if defined(__cpp_variable_templates) && __cpp_variable_templates >= 201304 // C++14
|
||||||
|
|
||||||
|
// void returning free overloaded functions
|
||||||
|
QVERIFY(qOverload<>(&freeOverloaded) ==
|
||||||
|
static_cast<void (*)()>(&freeOverloaded));
|
||||||
|
|
||||||
|
QVERIFY(qOverload<QByteArray>(&freeOverloaded) ==
|
||||||
|
static_cast<void (*)(QByteArray)>(&freeOverloaded));
|
||||||
|
|
||||||
|
QVERIFY((qOverload<QByteArray, const QString &>(&freeOverloaded)),
|
||||||
|
static_cast<void (*)(QByteArray, const QString &)>(&freeOverloaded));
|
||||||
|
|
||||||
|
// value returning free overloaded functions
|
||||||
|
QVERIFY(qOverload<>(&freeOverloadedGet) ==
|
||||||
|
static_cast<QByteArray (*)()>(&freeOverloadedGet));
|
||||||
|
|
||||||
|
QVERIFY(qOverload<QByteArray>(&freeOverloadedGet) ==
|
||||||
|
static_cast<void (*)(QByteArray)>(&freeOverloadedGet));
|
||||||
|
|
||||||
|
// void returning overloaded member functions
|
||||||
|
QVERIFY(qOverload<>(&Overloaded::foo) ==
|
||||||
|
static_cast<void (Overloaded::*)()>(&Overloaded::foo));
|
||||||
|
|
||||||
|
QVERIFY(qOverload<QByteArray>(&Overloaded::foo) ==
|
||||||
|
static_cast<void (Overloaded::*)(QByteArray)>(&Overloaded::foo));
|
||||||
|
|
||||||
|
QVERIFY((qOverload<QByteArray, const QString &>(&Overloaded::foo)) ==
|
||||||
|
static_cast<void (Overloaded::*)(QByteArray, const QString &)>(&Overloaded::foo));
|
||||||
|
|
||||||
|
// void returning overloaded const member functions
|
||||||
|
QVERIFY(qOverload<>(&Overloaded::constFoo) ==
|
||||||
|
static_cast<void (Overloaded::*)() const>(&Overloaded::constFoo));
|
||||||
|
|
||||||
|
QVERIFY(qOverload<QByteArray>(&Overloaded::constFoo) ==
|
||||||
|
static_cast<void (Overloaded::*)(QByteArray) const>(&Overloaded::constFoo));
|
||||||
|
|
||||||
|
QVERIFY((qOverload<QByteArray, const QString &>(&Overloaded::constFoo)) ==
|
||||||
|
static_cast<void (Overloaded::*)(QByteArray, const QString &) const>(&Overloaded::constFoo));
|
||||||
|
|
||||||
|
// void returning overloaded const AND non-const member functions
|
||||||
|
QVERIFY(qNonConstOverload<>(&Overloaded::mixedFoo) ==
|
||||||
|
static_cast<void (Overloaded::*)()>(&Overloaded::mixedFoo));
|
||||||
|
|
||||||
|
QVERIFY(qConstOverload<QByteArray>(&Overloaded::mixedFoo) ==
|
||||||
|
static_cast<void (Overloaded::*)(QByteArray) const>(&Overloaded::mixedFoo));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
QTEST_APPLESS_MAIN(tst_QGlobal)
|
QTEST_APPLESS_MAIN(tst_QGlobal)
|
||||||
#include "tst_qglobal.moc"
|
#include "tst_qglobal.moc"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user