QWeakPointer: use an alternative work-round for internalData() users
The previous work-around fails, probably because of
cross-dependencies. E.g. we have this in QtScXml:
In file included from /home/qt/work/install/include/QtCore/qsharedpointer.h:48:0,
from ../../src/scxml/qscxmltabledata_p.h:55,
from ../../src/scxml/qscxmltabledata.cpp:40:
/home/qt/work/install/include/QtCore/qsharedpointer_impl.h:687:12: error: ‘QPointer’ does not name a type; did you mean ‘pointer’?
friend QPointer<X>
^~~~~~~~
pointer
/home/qt/work/install/include/QtCore/qsharedpointer_impl.h:689:23: error: ‘QSmartPointerConvertFunctor’ in namespace ‘QtPrivate’ does not name a template type
friend QtPrivate::QSmartPointerConvertFunctor<QWeakPointer>;
^~~~~~~~~~~~~~~~~~~~~~~~~~~
To fix, grand friendship only to a non-template class with a templated
static method that returns internalData(). This fixes most users,
except in qmetatype.h, which does not include qsharedpointer.h. In
order to use the non-template class in there, we need to delay its
name lookup to instantiation time. We do this by artificially making
it a dependent name, by using a class template that inherits from
our befrieded class.
Change-Id: I12b427f1fe9503df819ea5436d780972d6402e68
Reviewed-by: Ville Voutilainen <ville.voutilainen@qt.io>
parent
fafae936a6
commit
242bc539ab
|
|
@ -1715,12 +1715,17 @@ namespace QtPrivate {
|
|||
}
|
||||
};
|
||||
|
||||
// hack to delay name lookup to instantiation time by making
|
||||
// EnableInternalData a dependent name:
|
||||
template <typename T>
|
||||
struct EnableInternalDataWrap;
|
||||
|
||||
template<typename T>
|
||||
struct QSmartPointerConvertFunctor<QWeakPointer<T> >
|
||||
{
|
||||
QObject* operator()(const QWeakPointer<T> &p) const
|
||||
{
|
||||
return p.internalData();
|
||||
return QtPrivate::EnableInternalDataWrap<T>::internalData(p);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -143,7 +143,8 @@ template<typename T>
|
|||
QPointer<T>
|
||||
qPointerFromVariant(const QVariant &variant)
|
||||
{
|
||||
return QPointer<T>(qobject_cast<T*>(QtSharedPointer::weakPointerFromVariant_internal(variant).internalData()));
|
||||
const auto wp = QtSharedPointer::weakPointerFromVariant_internal(variant);
|
||||
return QPointer<T>{qobject_cast<T*>(QtPrivate::EnableInternalData::internalData(wp))};
|
||||
}
|
||||
|
||||
template <class T>
|
||||
|
|
|
|||
|
|
@ -107,6 +107,10 @@ template <class X, class T>
|
|||
QSharedPointer<X> qSharedPointerObjectCast(const QSharedPointer<T> &ptr);
|
||||
#endif
|
||||
|
||||
namespace QtPrivate {
|
||||
struct EnableInternalData;
|
||||
}
|
||||
|
||||
namespace QtSharedPointer {
|
||||
template <class T> class ExternalRefCount;
|
||||
|
||||
|
|
@ -672,21 +676,12 @@ public:
|
|||
#endif
|
||||
|
||||
private:
|
||||
|
||||
friend struct QtPrivate::EnableInternalData;
|
||||
#if defined(Q_NO_TEMPLATE_FRIENDS)
|
||||
public:
|
||||
#else
|
||||
template <class X> friend class QSharedPointer;
|
||||
template <class X> friend class QPointer;
|
||||
# ifndef QT_NO_QOBJECT
|
||||
template<typename X>
|
||||
friend QWeakPointer<typename std::enable_if<QtPrivate::IsPointerToTypeDerivedFromQObject<X*>::Value, X>::type>
|
||||
qWeakPointerFromVariant(const QVariant &variant);
|
||||
# endif
|
||||
template<typename X>
|
||||
friend QPointer<X>
|
||||
qPointerFromVariant(const QVariant &variant);
|
||||
friend QtPrivate::QSmartPointerConvertFunctor<QWeakPointer>;
|
||||
#endif
|
||||
|
||||
template <class X>
|
||||
|
|
@ -721,6 +716,17 @@ public:
|
|||
T *value;
|
||||
};
|
||||
|
||||
namespace QtPrivate {
|
||||
struct EnableInternalData {
|
||||
template <typename T>
|
||||
static T *internalData(const QWeakPointer<T> &p) noexcept { return p.internalData(); }
|
||||
};
|
||||
// hack to delay name lookup to instantiation time by making
|
||||
// EnableInternalData a dependent name:
|
||||
template <typename T>
|
||||
struct EnableInternalDataWrap : EnableInternalData {};
|
||||
}
|
||||
|
||||
template <class T>
|
||||
class QEnableSharedFromThis
|
||||
{
|
||||
|
|
@ -996,7 +1002,7 @@ template<typename T>
|
|||
QWeakPointer<typename std::enable_if<QtPrivate::IsPointerToTypeDerivedFromQObject<T*>::Value, T>::type>
|
||||
qWeakPointerFromVariant(const QVariant &variant)
|
||||
{
|
||||
return QWeakPointer<T>(qobject_cast<T*>(QtSharedPointer::weakPointerFromVariant_internal(variant).internalData()));
|
||||
return QWeakPointer<T>(qobject_cast<T*>(QtPrivate::EnableInternalData::internalData(QtSharedPointer::weakPointerFromVariant_internal(variant))));
|
||||
}
|
||||
template<typename T>
|
||||
QSharedPointer<typename std::enable_if<QtPrivate::IsPointerToTypeDerivedFromQObject<T*>::Value, T>::type>
|
||||
|
|
|
|||
Loading…
Reference in New Issue