qHash(): make 1-to-2-arg adapter a worse match than regular 2-arg overloads

... by adding more arguments, but then constraining that they don't,
actually, exist.

This makes the the signature of a normal qHash(T, size_t) consistently
a better overload (for same T) than the 1-to-2 adapter. It doesn't
solve the problem that the adapter inserts hash functions for types
that were never defined to be hashable (cf. e.g. QTBUG-116076). But
the adapter is already slated for removal in Qt 7, which will solve
the issue, though maybe we can expedite its demise in 6.9.

Add the test from the bugreport to tst_QHashFunctions.

Fixes: QTBUG-126659
Change-Id: Idb3f275f0409652d55b318d56092764371269c06
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit 798c23189c7fb73629c1a98361cb1f50446fecf1)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Marc Mutz 2024-06-25 22:10:27 +02:00 committed by Qt Cherry-pick Bot
parent d699966713
commit aefa427459
2 changed files with 15 additions and 2 deletions

View File

@ -231,8 +231,10 @@ constexpr inline bool HasQHashSingleArgOverload<T, std::enable_if_t<
>> = true;
}
template <typename T, std::enable_if_t<QHashPrivate::HasQHashSingleArgOverload<T> && !std::is_enum_v<T>, bool> = true>
size_t qHash(const T &t, size_t seed) noexcept(noexcept(qHash(t)))
// Add Args... to make this overload consistently a worse match than
// original 2-arg qHash overloads (QTBUG-126659)
template <typename T, typename...Args, std::enable_if_t<QHashPrivate::HasQHashSingleArgOverload<T> && sizeof...(Args) == 0 && !std::is_enum_v<T>, bool> = true>
size_t qHash(const T &t, size_t seed, Args&&...) noexcept(noexcept(qHash(t)))
{ return qHash(t) ^ seed; }
#endif // < Qt 7

View File

@ -3,6 +3,8 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QTest>
#include <QtCore/qmap.h>
#include <QVarLengthArray>
#include <qhash.h>
@ -44,6 +46,7 @@ private Q_SLOTS:
void qhash_of_empty_and_null_qstring();
void qhash_of_empty_and_null_qbytearray();
void qhash_of_zero_floating_points();
void qmap();
void qthash_data();
void qthash();
void range();
@ -439,6 +442,14 @@ void tst_QHashFunctions::qhash_of_zero_floating_points()
QCOMPARE(qHash(-0.0L, seed), qHash(0.0L, seed));
}
void tst_QHashFunctions::qmap()
{
// QTBUG-126659
QMap<int, int> map;
size_t s = seed;
QCOMPARE(qHash(map, s), seed);
}
void tst_QHashFunctions::qthash_data()
{
QTest::addColumn<QString>("key");