From 7b0fc393a0a33d8a263a9a6c2f7daff6fac82c0a Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Mon, 9 Jan 2023 15:42:01 +0100 Subject: [PATCH] Move QTypeInfo from qpair.h to qtypeinfo.h to avoid ODR violation First off, this doesn't cost us anything, because std::pair is defined in , which qglobal.h unconditionally includes in C++ TUs. More importantly, it prevents ODR violations: when a TU includes only qtypeinfo.h, it will find std::pair to be of Q_COMPLEX_TYPE, in constrast with a TU which includes qpair.h, which will find it to be of Q_PRIMITIVE_TYPE instead. [ChangeLog][QtCore][QTypeInfo] The QTypeInfo for std::pair/QPair will now be correct even if qpair.h hasn't been included, fixing an One-Definition-Rule (ODR) violation. Change-Id: I51f579c123183af25aac9f0ffcf077f752848fb1 Reviewed-by: Thiago Macieira (cherry picked from commit f6b026eed1a4a3441ba9b1b92a9eaf2c17d69253) Reviewed-by: Qt Cherry-pick Bot --- src/corelib/global/qtypeinfo.h | 6 ++++++ src/corelib/tools/qpair.h | 3 --- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/corelib/global/qtypeinfo.h b/src/corelib/global/qtypeinfo.h index 60fd280a41e..1b9381321ec 100644 --- a/src/corelib/global/qtypeinfo.h +++ b/src/corelib/global/qtypeinfo.h @@ -81,6 +81,12 @@ public: static constexpr bool isIntegral = false; }; +// QTypeInfo for std::pair: +// std::pair is spec'ed to be struct { T1 first; T2 second; }, so, unlike tuple<>, +// we _can_ specialize QTypeInfo for pair<>: +template +class QTypeInfo> : public QTypeInfoMerger, T1, T2> {}; + #define Q_DECLARE_MOVABLE_CONTAINER(CONTAINER) \ template \ class QTypeInfo> \ diff --git a/src/corelib/tools/qpair.h b/src/corelib/tools/qpair.h index 75efaed3cf5..8070ca01755 100644 --- a/src/corelib/tools/qpair.h +++ b/src/corelib/tools/qpair.h @@ -22,9 +22,6 @@ constexpr decltype(auto) qMakePair(T1 &&value1, T2 &&value2) return std::make_pair(std::forward(value1), std::forward(value2)); } -template -class QTypeInfo> : public QTypeInfoMerger, T1, T2> {}; - QT_END_NAMESPACE #endif // QPAIR_H