QPointer: also provide a converting assignment operator
d026fad3d962eed0119351cd37f34490e09153fd added converting constructors for QPointer. This however made converting _assignments_ ambiguous, introducing a regression for users coming from Qt < 6.6. This code: QPointer<Base> base; QPointer<Derived> derived; base = derived; used to convert `derived` to `Derived *` (using the implicit conversion operator from `QPointer<Derived>` to `Derived *`), and then the assignment operator for `QPointer<Base>` that took a `Base *`. The introduction of the conversion constructor in 6.6 makes it possible to convert `QPointer<Derived>` to `QPointer<Base>`, and then fall back to the compiler-generated assignment operator for `QPointer<Base>`. The result is that the code above is now ambiguous and stops compiling. Fix this by adding a converting assignment operator for QPointer. I'm only adding the const-lvalue overload because the implementation requires going through the private QWeakPointer::assign helper. We cannot copy-assign or move-assign the inner QWeakPointer, as those assignments require lock()ing the QWeakPointer and that's not possible on a QObject-tracking QWeakPointer (but cf. QTBUG-117483). Assigning from a rvalue QPointer would mean calling assign() on the internal QWeakPointer _and_ clear the incoming QPointer, and that's strictly worse than the lvalue overload (where we just call assign()). Change-Id: I33fb2a22b3d5110284d78e3d7c6cc79a5b73b67b Pick-to: 6.6.0 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> (cherry picked from commit 6c504f2519e1180dbcfd77d5bb08b0db9742eeaa) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
411a213f65
commit
11aa3b13b3
@ -111,6 +111,17 @@
|
|||||||
is convertible to \c{T*}.
|
is convertible to \c{T*}.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn template <class T> template <class X> QPointer<T> &QPointer<T>::operator=(const QPointer<X> &other)
|
||||||
|
\since 6.6
|
||||||
|
|
||||||
|
Conversion assignment operator. Makes this guarded pointer guard the
|
||||||
|
same object guarded by \a other.
|
||||||
|
|
||||||
|
\note This operator participates in overload resolution only if \c{X*}
|
||||||
|
is convertible to \c{T*}.
|
||||||
|
*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\fn template <class T> void QPointer<T>::swap(QPointer &other)
|
\fn template <class T> void QPointer<T>::swap(QPointer &other)
|
||||||
\since 5.6
|
\since 5.6
|
||||||
|
@ -43,6 +43,13 @@ public:
|
|||||||
QPointer(const QPointer<X> &other) noexcept
|
QPointer(const QPointer<X> &other) noexcept
|
||||||
: wp(other.wp.internalData(), true) {}
|
: wp(other.wp.internalData(), true) {}
|
||||||
|
|
||||||
|
template <typename X, if_convertible<X> = true>
|
||||||
|
QPointer &operator=(const QPointer<X> &other)
|
||||||
|
{
|
||||||
|
wp.assign(other.data());
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef Q_QDOC
|
#ifdef Q_QDOC
|
||||||
// Stop qdoc from complaining about missing function
|
// Stop qdoc from complaining about missing function
|
||||||
~QPointer();
|
~QPointer();
|
||||||
|
@ -57,6 +57,19 @@ void tst_QPointer::conversion()
|
|||||||
QCOMPARE_EQ(pio.get(), &file);
|
QCOMPARE_EQ(pio.get(), &file);
|
||||||
QCOMPARE_EQ(pio, pf);
|
QCOMPARE_EQ(pio, pf);
|
||||||
QCOMPARE_EQ(pio.get(), pf.get());
|
QCOMPARE_EQ(pio.get(), pf.get());
|
||||||
|
|
||||||
|
// reset
|
||||||
|
pio = nullptr;
|
||||||
|
QCOMPARE_EQ(pio, nullptr);
|
||||||
|
QCOMPARE_EQ(pio.get(), nullptr);
|
||||||
|
|
||||||
|
// copy-assignment
|
||||||
|
QCOMPARE_EQ(pf, &file);
|
||||||
|
pio = pf;
|
||||||
|
QCOMPARE_EQ(pio, &file);
|
||||||
|
QCOMPARE_EQ(pio.get(), &file);
|
||||||
|
QCOMPARE_EQ(pio, pf);
|
||||||
|
QCOMPARE_EQ(pio.get(), pf.get());
|
||||||
}
|
}
|
||||||
// move-conversion:
|
// move-conversion:
|
||||||
{
|
{
|
||||||
@ -67,6 +80,16 @@ void tst_QPointer::conversion()
|
|||||||
QCOMPARE_EQ(pf, nullptr);
|
QCOMPARE_EQ(pf, nullptr);
|
||||||
QCOMPARE_EQ(pio, &file);
|
QCOMPARE_EQ(pio, &file);
|
||||||
QCOMPARE_EQ(pio.get(), &file);
|
QCOMPARE_EQ(pio.get(), &file);
|
||||||
|
|
||||||
|
// reset
|
||||||
|
pio = nullptr;
|
||||||
|
QCOMPARE_EQ(pio, nullptr);
|
||||||
|
QCOMPARE_EQ(pio.get(), nullptr);
|
||||||
|
|
||||||
|
// move-assignment
|
||||||
|
pio = QPointer<QFile>(&file);
|
||||||
|
QCOMPARE_EQ(pio, &file);
|
||||||
|
QCOMPARE_EQ(pio.get(), &file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user