QScopeGuard: Fix build failures with qScopeGuard()

Partially reverts 4f077b7e5f.

Can't overload with forwarding references and lvalue references. Use a single
forwarding reference overload, but take care of not trying to create a
QScopeGuard of reference type and forward instead of moving.

Add tests to ensure calling with both lvalues and rvalues is possible.

Change-Id: Ia034afe0a8feb08246c2c7c154a85cae37421c98
Reviewed-by: Ville Voutilainen <ville.voutilainen@qt.io>
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
This commit is contained in:
Kari Oikarinen 2020-01-30 12:46:47 +02:00
parent beede51bca
commit 89f443dfbc
2 changed files with 19 additions and 12 deletions

View File

@ -43,6 +43,8 @@
#include <QtCore/qglobal.h> #include <QtCore/qglobal.h>
#include <type_traits>
#include <utility>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@ -98,18 +100,9 @@ template <typename F>
#if __has_cpp_attribute(nodiscard) #if __has_cpp_attribute(nodiscard)
Q_REQUIRED_RESULT Q_REQUIRED_RESULT
#endif #endif
QScopeGuard<F> qScopeGuard(F &&f) QScopeGuard<typename std::decay<F>::type> qScopeGuard(F &&f)
{ {
return QScopeGuard<F>(std::move(f)); return QScopeGuard<typename std::decay<F>::type>(std::forward<F>(f));
}
template <typename F>
#if __has_cpp_attribute(nodiscard)
Q_REQUIRED_RESULT
#endif
QScopeGuard<F> qScopeGuard(const F &f)
{
return QScopeGuard<F>(f);
} }
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -112,12 +112,19 @@ void tst_QScopeGuard::constructionFromLvalue()
{ {
#ifdef __cpp_deduction_guides #ifdef __cpp_deduction_guides
Callable::resetCounts(); Callable::resetCounts();
Callable callable;
{ {
Callable callable;
QScopeGuard guard(callable); QScopeGuard guard(callable);
} }
QCOMPARE(Callable::copied, 1); QCOMPARE(Callable::copied, 1);
QCOMPARE(Callable::moved, 0); QCOMPARE(Callable::moved, 0);
Callable::resetCounts();
{
Callable callable;
auto guard = qScopeGuard(callable);
}
QCOMPARE(Callable::copied, 1);
QCOMPARE(Callable::moved, 0);
#else #else
QSKIP("This test requires C++17 Class Template Argument Deduction support enabled in the compiler."); QSKIP("This test requires C++17 Class Template Argument Deduction support enabled in the compiler.");
#endif #endif
@ -133,6 +140,13 @@ void tst_QScopeGuard::constructionFromRvalue()
} }
QCOMPARE(Callable::copied, 0); QCOMPARE(Callable::copied, 0);
QCOMPARE(Callable::moved, 1); QCOMPARE(Callable::moved, 1);
Callable::resetCounts();
{
Callable callable;
auto guard = qScopeGuard(std::move(callable));
}
QCOMPARE(Callable::copied, 0);
QCOMPARE(Callable::moved, 1);
#else #else
QSKIP("This test requires C++17 Class Template Argument Deduction support enabled in the compiler."); QSKIP("This test requires C++17 Class Template Argument Deduction support enabled in the compiler.");
#endif #endif