-
Bug
-
Resolution: Won't Do
-
P4: Low
-
None
-
5.2.0, 5.2.1, 5.3.0
-
None
-
MinGW 4.8.2
"qlist.h line 370 (Qt 5.3.0 sources)"
template <typename T> Q_INLINE_TEMPLATE void QList<T>::node_construct(Node *n, const T &t) { if (QTypeInfo<T>::isLarge || QTypeInfo<T>::isStatic) n->v = new T(t); else if (QTypeInfo<T>::isComplex) new (n) T(t); #if (defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__IBMCPP__)) && !defined(__OPTIMIZE__) // This violates pointer aliasing rules, but it is known to be safe (and silent) // in unoptimized GCC builds (-fno-strict-aliasing). The other compilers which // set the same define are assumed to be safe. else *reinterpret_cast<T*>(n) = t; #else // This is always safe, but penaltizes unoptimized builds a lot. else ::memcpy(n, static_cast<const void *>(&t), sizeof(T)); #endif }
As everything is in one method. Every part has to compile for every type.
If I have a T class which is not copyable:
"Column.h"
class Column { Column& operator =(const Column& src) = delete; public: explicit Column(const QString &name); private: const QString m_name; }
The QList<Column> is only valid with GCC in release mode.
suggested solution:
- use template specialisation to split the code at compile time.
"Add to QList<T>"
template < int isSeparate, int isComplex, int dummy = 1 > struct NodeConstructor;
"Extend node_construct"
template <typename T> template <int isComplex> struct QList<T>::NodeConstructor<true, isComplex> { static void construct(QList<T>::Node *n, const T &t) { n->v = new T(t); } }; template <typename T> template <int dummy> struct QList<T>::NodeConstructor<false, true, dummy> { static void construct(QList<T>::Node *n, const T &t) { new (n) T(t); } }; template<typename T> template<int dummy> struct QList<T>::NodeConstructor<false, false, dummy> { static void construct(QList<T>::Node *n, const T &t) { #if (defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__IBMCPP__)) && !defined(__OPTIMIZE__) // This violates pointer aliasing rules, but it is known to be safe (and silent) // in unoptimized GCC builds (-fno-strict-aliasing). The other compilers which // set the same define are assumed to be safe. *reinterpret_cast<T*>(n) = t; #else // This is always safe, but penaltizes unoptimized builds a lot. ::memcpy(n, static_cast<const void *>(&t), sizeof(T)); #endif } }; template <typename T> Q_INLINE_TEMPLATE void QList<T>::node_construct(Node *n, const T &t) { NodeConstructor<QTypeInfo<T>::isLarge || QTypeInfo<T>::isStatic, QTypeInfo<T>::isComplex>::construct(n, t); }