diff --git a/src/corelib/kernel/qpointer.cpp b/src/corelib/kernel/qpointer.cpp index aebdd68428b..c884844db3a 100644 --- a/src/corelib/kernel/qpointer.cpp +++ b/src/corelib/kernel/qpointer.cpp @@ -97,6 +97,20 @@ pointed to. */ +/*! + \fn template template QPointer::QPointer(QPointer &&other) + \fn template template QPointer::QPointer(const QPointer &other) + \since 6.6 + + Conversion constructor. Constructs a new QPointer by moving or copying from + \a other. + + The moved-from QPointer is reset to nullptr. + + \note These constructors participate in overload resolution only if \c{X*} + is convertible to \c{T*}. +*/ + /*! \fn template void QPointer::swap(QPointer &other) \since 5.6 diff --git a/src/corelib/kernel/qpointer.h b/src/corelib/kernel/qpointer.h index 2c824411641..ada4445d43d 100644 --- a/src/corelib/kernel/qpointer.h +++ b/src/corelib/kernel/qpointer.h @@ -18,6 +18,11 @@ class QPointer { static_assert(!std::is_pointer::value, "QPointer's template type must not be a pointer type"); + template + using if_convertible = std::enable_if_t, bool>; + template + friend class QPointer; + using QObjectType = typename std::conditional::value, const QObject, QObject>::type; QWeakPointer wp; @@ -27,6 +32,11 @@ public: // compiler-generated copy/move ctor/assignment operators are fine! // compiler-generated dtor is fine! + template = true> + QPointer(QPointer &&other) noexcept : wp(std::move(other.wp)) {} + template = true> + QPointer(const QPointer &other) noexcept : wp(other.wp) {} + #ifdef Q_QDOC // Stop qdoc from complaining about missing function ~QPointer(); diff --git a/tests/auto/corelib/kernel/qpointer/tst_qpointer.cpp b/tests/auto/corelib/kernel/qpointer/tst_qpointer.cpp index 9886ab84f29..0af37237044 100644 --- a/tests/auto/corelib/kernel/qpointer/tst_qpointer.cpp +++ b/tests/auto/corelib/kernel/qpointer/tst_qpointer.cpp @@ -19,6 +19,7 @@ public: private slots: void constructors(); + void conversion(); void destructor(); void assignment_operators(); void equality_operators(); @@ -44,6 +45,31 @@ void tst_QPointer::constructors() QCOMPARE(p3, QPointer(this)); } +void tst_QPointer::conversion() +{ + // copy-conversion: + { + QFile file; + QPointer pf = &file; + QCOMPARE_EQ(pf, &file); + QPointer pio = pf; + QCOMPARE_EQ(pio, &file); + QCOMPARE_EQ(pio.get(), &file); + QCOMPARE_EQ(pio, pf); + QCOMPARE_EQ(pio.get(), pf.get()); + } + // move-conversion: + { + QFile file; + QPointer pf = &file; + QCOMPARE_EQ(pf, &file); + QPointer pio = std::move(pf); + QCOMPARE_EQ(pf, nullptr); + QCOMPARE_EQ(pio, &file); + QCOMPARE_EQ(pio.get(), &file); + } +} + void tst_QPointer::destructor() { // Make two QPointer's to the same object