summaryrefslogtreecommitdiffstats
path: root/src/corelib/tools/qhash.cpp
diff options
context:
space:
mode:
authorGiuseppe D'Angelo <giuseppe.dangelo@kdab.com>2020-11-27 17:39:10 +0100
committerGiuseppe D'Angelo <giuseppe.dangelo@kdab.com>2020-11-30 17:16:22 +0100
commit81e893fb2d57b7f2d332f4f626e38f51acf43542 (patch)
treeb8bc1fc0a30a6419f75094433cdf52025e5f0da0 /src/corelib/tools/qhash.cpp
parent5dab710b90e7041aaa9fcf3631f2ca6af1baab5f (diff)
QHash: support std::hash as hashing function
In addition (and as a fallback) from requiring qHash, add support for std::hash specializations. This catches two birds with one stone: 1) users of Qt can simply specialize std::hash for their datatypes, and use them in both QHash and stdlib unordered associative containers; 2) we get QHash support for any (stdlib) datatype that is hashable without having to overload qHash for them. [ChangeLog][QtCore][QHash] QHash, QMultiHash and QSet now support for key types anything that can be hashed via std::hash, instead of always requiring a qHash() overload. Change-Id: Ib5ecba86e4b376d318389500bd24883ac6534c5f Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Lars Knoll <lars.knoll@qt.io> Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
Diffstat (limited to 'src/corelib/tools/qhash.cpp')
-rw-r--r--src/corelib/tools/qhash.cpp40
1 files changed, 30 insertions, 10 deletions
diff --git a/src/corelib/tools/qhash.cpp b/src/corelib/tools/qhash.cpp
index 112a492526..8a94695ec3 100644
--- a/src/corelib/tools/qhash.cpp
+++ b/src/corelib/tools/qhash.cpp
@@ -1194,22 +1194,26 @@ size_t qHash(long double key, size_t seed) noexcept
instead, store a QWidget *.
\target qHash
- \section2 The qHash() hashing function
+ \section2 The hashing function
A QHash's key type has additional requirements other than being an
assignable data type: it must provide operator==(), and there must also be
- a qHash() function in the type's namespace that returns a hash value for an
- argument of the key's type.
+ a hashing function that returns a hash value for an argument of the
+ key's type.
- The qHash() function computes a numeric value based on a key. It
+ The hashing function computes a numeric value based on a key. It
can use any algorithm imaginable, as long as it always returns
the same value if given the same argument. In other words, if
- \c{e1 == e2}, then \c{qHash(e1) == qHash(e2)} must hold as well.
- However, to obtain good performance, the qHash() function should
+ \c{e1 == e2}, then \c{hash(e1) == hash(e2)} must hold as well.
+ However, to obtain good performance, the hashing function should
attempt to return different hash values for different keys to the
largest extent possible.
- For a key type \c{K}, the qHash function must have one of these signatures:
+ A hashing function for a key type \c{K} may be provided in two
+ different ways.
+
+ The first way is by having an overload of \c{qHash()} in \c{K}'s
+ namespace. The \c{qHash()} function must have one of these signatures:
\snippet code/src_corelib_tools_qhash.cpp 32
@@ -1220,6 +1224,20 @@ size_t qHash(long double key, size_t seed) noexcept
the latter is used by QHash (note that you can simply define a
two-arguments version, and use a default value for the seed parameter).
+ The second way to provide a hashing function is by specializing
+ the \c{std::hash} class for the key type \c{K}, and providing a
+ suitable function call operator for it:
+
+ \snippet code/src_corelib_tools_qhash.cpp 33
+
+ The seed argument has the same meaning as for \c{qHash()},
+ and may be left out.
+
+ This second way allows to reuse the same hash function between
+ QHash and the C++ Standard Library unordered associative containers.
+ If both a \c{qHash()} overload and a \c{std::hash} specializations
+ are provided for a type, then the \c{qHash()} overload is preferred.
+
Here's a partial list of the C++ and Qt types that can serve as keys in a
QHash: any integer type (char, unsigned long, etc.), any pointer type,
QChar, QString, and QByteArray. For all of these, the \c <QHash> header
@@ -1228,9 +1246,11 @@ size_t qHash(long double key, size_t seed) noexcept
the documentation of each class.
If you want to use other types as the key, make sure that you provide
- operator==() and a qHash() implementation. The convenience qHashMulti()
- function can be used to implement qHash() for a custom type, where
- one usually wants to produce a hash value from multiple fields:
+ operator==() and a hash implementation.
+
+ The convenience qHashMulti() function can be used to implement
+ qHash() for a custom type, where one usually wants to produce a
+ hash value from multiple fields:
Example:
\snippet code/src_corelib_tools_qhash.cpp 13