The <QtAlgorithms> header includes the generic, template-based algorithms.
Qt provides a number of global template functions in
<QtAlgorithms>
that work on containers and perform small tasks to make life easier, such asqDeleteAll()
, which invokesoperator delete
on all items in a given container or in a given range. You can use these algorithms with any container class that provides STL-style iterators, including Qt’sQList
,QLinkedList
,QVector
,QMap
, andQHash
classes.Most algorithms take STL-style iterators as parameters. The algorithms are generic in the sense that they aren’t bound to a specific iterator class; you can use them with any iterators that meet a certain set of requirements.
Different algorithms can have different requirements for the iterators they accept. For example,
qFill()
accepts two forward iterators . The iterator types required are specified for each algorithm. If an iterator of the wrong type is passed (for example, ifConstIterator
is passed as an output iterator ), you will always get a compiler error, although not necessarily a very informative one.Some algorithms have special requirements on the value type stored in the containers. For example,
qDeleteAll()
requires that the value type is a non-const pointer type (for example,QWidget
*). The value type requirements are specified for each algorithm, and the compiler will produce an error if a requirement isn’t met.The generic algorithms can be used on other container classes than those provided by Qt and STL. The syntax of STL-style iterators is modeled after C++ pointers, so it’s possible to use plain arrays as containers and plain pointers as iterators. A common idiom is to use
qBinaryFind()
together with two static arrays: one that contains a list of keys, and another that contains a list of associated values. For example, the following code will look up an HTML entity (e.g.,&
;) in thename_table
array and return the corresponding Unicode value from thevalue_table
if the entity is recognized:QChar resolveEntity(const QString &entity) { static const QLatin1String name_table[] = { "AElig", "Aacute", ..., "zwnj" }; static const ushort value_table[] = { 0x0061, 0x00c1, ..., 0x200c }; int N = sizeof(name_table) / sizeof(name_table[0]); const QLatin1String *name = qBinaryFind(name_table, name_table + N, entity); int index = name - name_table; if (index == N) return QChar(); return QChar(value_table[index]); }This kind of code is for advanced users only; for most applications, a
QMap
- orQHash
-based approach would work just as well:QChar resolveEntity(const QString &entity) { static QMap<QString, int> entityMap; if (!entityMap) { entityMap.insert("AElig", 0x0061); entityMap.insert("Aacute", 0x00c1); ... entityMap.insert("zwnj", 0x200c); } return QChar(entityMap.value(entity)); }
Types of Iterators¶
The algorithms have certain requirements on the iterator types they accept, and these are specified individually for each function. The compiler will produce an error if a requirement isn’t met.
Input Iterators¶
An input iterator is an iterator that can be used for reading data sequentially from a container. It must provide the following operators:
==
and!=
for comparing two iterators, unary*
for retrieving the value stored in the item, and prefix++
for advancing to the next item.The Qt containers’ iterator types (const and non-const) are all input iterators.
Output Iterators¶
An output iterator is an iterator that can be used for writing data sequentially to a container or to some output stream. It must provide the following operators: unary
*
for writing a value (i.e.,*it = val
) and prefix++
for advancing to the next item.The Qt containers’ non-const iterator types are all output iterators.
Forward Iterators¶
A forward iterator is an iterator that meets the requirements of both input iterators and output iterators.
The Qt containers’ non-const iterator types are all forward iterators.
Bidirectional Iterators¶
A bidirectional iterator is an iterator that meets the requirements of forward iterators but that in addition supports prefix
--
for iterating backward.The Qt containers’ non-const iterator types are all bidirectional iterators.
Random Access Iterators¶
The last category, random access iterators , is the most powerful type of iterator. It supports all the requirements of a bidirectional iterator, and supports the following operations:
i += n
advances iterator
i
byn
positions
i -= n
moves iterator
i
back byn
positions
i + n
orn + i
returns the iterator for the item
n
positions ahead of iteratori
i - n
returns the iterator for the item
n
positions behind of iteratori
i - j
returns the number of items between iterators
i
andj
i[n]
same as
*(i + n)
i < j
returns
true
if iteratorj
comes after iteratori
QList
andQVector
‘s non-const iterator types are random access iterators.
Qt and the STL Algorithms¶
Historically, Qt used to provide functions which were direct equivalents of many STL algorithmic functions. Starting with Qt 5.0, you are instead encouraged to use directly the implementations available in the STL; most of the Qt ones have been deprecated (although they are still available to keep the old code compiling).
Porting guidelines¶
Most of the time, an application using the deprecated Qt algorithmic functions can be easily ported to use the equivalent STL functions. You need to:
add the
#include <algorithm>
preprocessor directive;replace the Qt functions with the STL counterparts, according to the table below.
Qt function
STL function
qBinaryFind
std::binary_search
orstd::lower_bound
qCopy
std::copy
qCopyBackward
std::copy_backward
qEqual
std::equal
qFill
std::fill
qFind
std::find
qCount
std::count
qSort
std::sort
qStableSort
std::stable_sort
qLowerBound
std::lower_bound
qUpperBound
std::upper_bound
qLess
std::less
qGreater
std::greater
The only cases in which the port may not be straightforward is if the old code relied on template specializations of the
qLess()
and/or theqSwap()
functions, which were used internally by the implementations of the Qt algorithmic functions, but are instead ignored by the STL ones.In case the old code relied on the specialization of the
qLess()
functor, then a workaround is explicitly passing an instance of theqLess()
class to the STL function, for instance like this:std::sort(container.begin(), container.end(), qLess<T>());Instead, since it’s not possible to pass a custom swapper functor to STL functions, the only workaround for a template specialization for
qSwap()
is providing the same specialization forstd::swap()
.See also
container classes <QtGlobal>
Use
std::binary_search
orstd::lower_bound
instead.Performs a binary search of the range [
begin
,end
) and returns the position of an occurrence ofvalue
. If there are no occurrences ofvalue
, returnsend
.The items in the range [
begin
,end
) must be sorted in ascending order; seeqSort()
.If there are many occurrences of the same value, any one of them could be returned. Use
qLowerBound()
orqUpperBound()
if you need finer control.Example:
QVector<int> vect; vect << 3 << 3 << 6 << 6 << 6 << 8; QVector<int>::iterator i = qBinaryFind(vect.begin(), vect.end(), 6); // i == vect.begin() + 2 (or 3 or 4)This function requires the item type (in the example above,
QString
) to implementoperator<()
.See also
qLowerBound()
qUpperBound()
random access iteratorsThis is an overloaded function.
Use
std::binary_search
orstd::lower_bound
instead.Uses the
lessThan
function instead ofoperator<()
to compare the items.Note that the items in the range must be sorted according to the order specified by the
lessThan
object.This is an overloaded function.
Use
std::binary_search
orstd::lower_bound
instead.This is the same as
qBinaryFind
(container
.begin(),container
.end(),value
);Use
std::copy
instead.Copies the items from range [
begin1
,end1
) to range [begin2
, …), in the order in which they appear.The item at position
begin1
is assigned to that at positionbegin2
; the item at positionbegin1
+ 1 is assigned to that at positionbegin2
+ 1; and so on.Example:
QStringList list; list << "one" << "two" << "three"; QVector<QString> vect1(3); qCopy(list.begin(), list.end(), vect1.begin()); // vect: [ "one", "two", "three" ] QVector<QString> vect2(8); qCopy(list.begin(), list.end(), vect2.begin() + 2); // vect: [ "", "", "one", "two", "three", "", "", "" ]See also
qCopyBackward()
input iterators output iteratorsUse
std::copy_backward
instead.Copies the items from range [
begin1
,end1
) to range […,end2
).The item at position
end1
- 1 is assigned to that at positionend2
- 1; the item at positionend1
- 2 is assigned to that at positionend2
- 2; and so on.Example:
QStringList list; list << "one" << "two" << "three"; QVector<QString> vect(5); qCopyBackward(list.begin(), list.end(), vect.end()); // vect: [ "", "", "one", "two", "three" ]See also
qCopy()
bidirectional iteratorsUse
std::count
instead.Returns the number of occurrences of
value
in the range [begin
,end
), which is returned inn
.n
is never initialized, the count is added ton
. It is the caller’s responsibility to initializen
.Example:
QList<int> list; list << 3 << 3 << 6 << 6 << 6 << 8; int countOf6 = 0; qCount(list.begin(), list.end(), 6, countOf6); // countOf6 == 3 int countOf7 = 0; qCount(list.begin(), list.end(), 7, countOf7); // countOf7 == 0This function requires the item type (in the example above,
int
) to implementoperator==()
.See also
input iterators
This is an overloaded function.
Use
std::count
instead.Instead of operating on iterators, as in the other overload, this function operates on the specified
container
to obtain the number of instances ofvalue
in the variable passed as a reference in argumentn
.Returns the number of consecutive zero bits in
v
, when searching from the MSB. For example, (quint8(1)) returns 7 and (quint8(8)) returns 4.Returns the number of consecutive zero bits in
v
, when searching from the MSB. For example,qCountLeadingZeroBits
(quint16(1)) returns 15 andqCountLeadingZeroBits
(quint16(8)) returns 12.Returns the number of consecutive zero bits in
v
, when searching from the MSB. For example,qCountLeadingZeroBits
(quint64(1)) returns 63 andqCountLeadingZeroBits
(quint64(8)) returns 60.Returns the number of consecutive zero bits in
v
, when searching from the LSB. For example, (1) returns 0 and (8) returns 3.This is an overloaded function.
This is an overloaded function.
This is an overloaded function.
Deletes all the items in the range [
begin
,end
) using the C++delete
operator. The item type must be a pointer type (for example,QWidget *
).Example:
QList<Employee *> list; list.append(new Employee("Blackpool", "Stephen")); list.append(new Employee("Twist", "Oliver")); qDeleteAll(list.begin(), list.end()); list.clear();Notice that doesn’t remove the items from the container; it merely calls
delete
on them. In the example above, we call clear() on the container to remove the items.This function can also be used to delete items stored in associative containers, such as
QMap
andQHash
. Only the objects stored in each container will be deleted by this function; objects used as keys will not be deleted.See also
forward iterators
This is an overloaded function.
This is the same as
qDeleteAll
(c
.begin(),c
.end()).Use
std::equal
instead.Compares the items in the range [
begin1
,end1
) with the items in the range [begin2
, …). Returnstrue
if all the items compare equal; otherwise returnsfalse
.Example:
QStringList list; list << "one" << "two" << "three"; QVector<QString> vect(3); vect[0] = "one"; vect[1] = "two"; vect[2] = "three"; bool ret1 = qEqual(list.begin(), list.end(), vect.begin()); // ret1 == true vect[2] = "seven"; bool ret2 = qEqual(list.begin(), list.end(), vect.begin()); // ret2 == falseThis function requires the item type (in the example above,
QString
) to implementoperator==()
.See also
input iterators
Use
std::fill
instead.Fills the range [
begin
,end
) withvalue
.Example:
QStringList list; list << "one" << "two" << "three"; qFill(list.begin(), list.end(), "eleven"); // list: [ "eleven", "eleven", "eleven" ] qFill(list.begin() + 1, list.end(), "six"); // list: [ "eleven", "six", "six" ]See also
qCopy()
forward iteratorsThis is an overloaded function.
Use
std::fill
instead.This is the same as
qFill
(container
.begin(),container
.end(),value
);Use
std::find
instead.Returns an iterator to the first occurrence of
value
in a container in the range [begin
,end
). Returnsend
ifvalue
isn’t found.Example:
QStringList list; list << "one" << "two" << "three"; QStringList::iterator i1 = qFind(list.begin(), list.end(), "two"); // i1 == list.begin() + 1 QStringList::iterator i2 = qFind(list.begin(), list.end(), "seventy"); // i2 == list.end()This function requires the item type (in the example above,
QString
) to implementoperator==()
.If the items in the range are in ascending order, you can get faster results by using
qLowerBound()
orqBinaryFind()
instead of .See also
qBinaryFind()
input iteratorsThis is an overloaded function.
Use
std::find
instead.This is the same as
qFind
(container
.constBegin(),container
.constEnd(),value
);Use
std::greater
instead.Returns a functional object, or functor, that can be passed to
qSort()
orqStableSort()
.Example:
QList<int> list; list << 33 << 12 << 68 << 6 << 12; qSort(list.begin(), list.end(), qGreater<int>()); // list: [ 68, 33, 12, 12, 6 ]See also
qLess
Use
std::less
instead.Returns a functional object, or functor, that can be passed to
qSort()
orqStableSort()
.Example:
QList<int> list; list << 33 << 12 << 68 << 6 << 12; qSort(list.begin(), list.end(), qLess<int>()); // list: [ 6, 12, 12, 33, 68 ]See also
qGreater
Use
std::lower_bound
instead.Performs a binary search of the range [
begin
,end
) and returns the position of the first occurrence ofvalue
. If no such item is found, returns the position where it should be inserted.The items in the range [
begin
, end ) must be sorted in ascending order; seeqSort()
.Example:
QList<int> list; list << 3 << 3 << 6 << 6 << 6 << 8; QList<int>::iterator i = qLowerBound(list.begin(), list.end(), 5); list.insert(i, 5); // list: [ 3, 3, 5, 6, 6, 6, 8 ] i = qLowerBound(list.begin(), list.end(), 12); list.insert(i, 12); // list: [ 3, 3, 5, 6, 6, 6, 8, 12 ]This function requires the item type (in the example above,
int
) to implementoperator<()
.can be used in conjunction with
qUpperBound()
to iterate over all occurrences of the same value:QVector<int> vect; vect << 3 << 3 << 6 << 6 << 6 << 8; QVector<int>::iterator begin6 = qLowerBound(vect.begin(), vect.end(), 6); QVector<int>::iterator end6 = qUpperBound(begin6, vect.end(), 6); QVector<int>::iterator i = begin6; while (i != end6) { *i = 7; ++i; } // vect: [ 3, 3, 7, 7, 7, 8 ]See also
qUpperBound()
qBinaryFind()
This is an overloaded function.
Use
std::lower_bound
instead.Uses the
lessThan
function instead ofoperator<()
to compare the items.Note that the items in the range must be sorted according to the order specified by the
lessThan
object.This is an overloaded function.
Use
std::lower_bound
instead.For read-only iteration over containers, this function is broadly equivalent to
qLowerBound
(container
.begin(),container
.end(), value). However, since it returns a const iterator, you cannot use it to modify the container; for example, to insert items.Returns the number of bits set in
v
. This number is also called the Hamming Weight ofv
.This is an overloaded function.
This is an overloaded function.
This is an overloaded function.
Use
std::sort
instead.Sorts the items in range [
begin
,end
) in ascending order using the quicksort algorithm.Example:
QList<int> list; list << 33 << 12 << 68 << 6 << 12; qSort(list.begin(), list.end()); // list: [ 6, 12, 12, 33, 68 ]The sort algorithm is efficient on large data sets. It operates in linear-logarithmic time , O(n log n ).
This function requires the item type (in the example above,
int
) to implementoperator<()
.If neither of the two items is “less than” the other, the items are taken to be equal. It is then undefined which one of the two items will appear before the other after the sort.
See also
qStableSort()
random access iteratorsThis is an overloaded function.
Use
std::sort
instead.Uses the
lessThan
function instead ofoperator<()
to compare the items.For example, here’s how to sort the strings in a
QStringList
in case-insensitive alphabetical order:bool caseInsensitiveLessThan(const QString &s1, const QString &s2) { return s1.toLower() < s2.toLower(); } int doSomething() { QStringList list; list << "AlPha" << "beTA" << "gamma" << "DELTA"; qSort(list.begin(), list.end(), caseInsensitiveLessThan); // list: [ "AlPha", "beTA", "DELTA", "gamma" ] }To sort values in reverse order, pass
qGreater
as thelessThan
parameter. For example:QList<int> list; list << 33 << 12 << 68 << 6 << 12; qSort(list.begin(), list.end(), qGreater<int>()); // list: [ 68, 33, 12, 12, 6 ]If neither of the two items is “less than” the other, the items are taken to be equal. It is then undefined which one of the two items will appear before the other after the sort.
An alternative to using
qSort()
is to put the items to sort in aQMap
, using the sort key as theQMap
key. This is often more convenient than defining alessThan
function. For example, the following code shows how to sort a list of strings case insensitively usingQMap
:QStringList list; list << "AlPha" << "beTA" << "gamma" << "DELTA"; QMap<QString, QString> map; foreach (const QString &str, list) map.insert(str.toLower(), str); list = map.values();See also
QMap
This is an overloaded function.
Use
std::sort
instead.This is the same as
qSort
(container
.begin(),container
.end());Use
std::stable_sort
instead.Sorts the items in range [
begin
,end
) in ascending order using a stable sorting algorithm.If neither of the two items is “less than” the other, the items are taken to be equal. The item that appeared before the other in the original container will still appear first after the sort. This property is often useful when sorting user-visible data.
Example:
QList<int> list; list << 33 << 12 << 68 << 6 << 12; qStableSort(list.begin(), list.end()); // list: [ 6, 12, 12, 33, 68 ]The sort algorithm is efficient on large data sets. It operates in linear-logarithmic time , O(n log n ).
This function requires the item type (in the example above,
int
) to implementoperator<()
.See also
qSort()
random access iteratorsThis is an overloaded function.
Use
std::stable_sort
instead.Uses the
lessThan
function instead ofoperator<()
to compare the items.For example, here’s how to sort the strings in a
QStringList
in case-insensitive alphabetical order:bool caseInsensitiveLessThan(const QString &s1, const QString &s2) { return s1.toLower() < s2.toLower(); } int doSomething() { QStringList list; list << "AlPha" << "beTA" << "gamma" << "DELTA"; qStableSort(list.begin(), list.end(), caseInsensitiveLessThan); // list: [ "AlPha", "beTA", "DELTA", "gamma" ] }Note that earlier versions of Qt allowed using a lessThan function that took its arguments by non-const reference. From 4.3 and on this is no longer possible, the arguments has to be passed by const reference or value.
To sort values in reverse order, pass
qGreater
as thelessThan
parameter. For example:QList<int> list; list << 33 << 12 << 68 << 6 << 12; qStableSort(list.begin(), list.end(), qGreater<int>()); // list: [ 68, 33, 12, 12, 6 ]If neither of the two items is “less than” the other, the items are taken to be equal. The item that appeared before the other in the original container will still appear first after the sort. This property is often useful when sorting user-visible data.
This is an overloaded function.
Use
std::stable_sort
instead.This is the same as
qStableSort
(container
.begin(),container
.end());Use
std::swap
instead.Exchanges the values of variables
var1
andvar2
.Example:
double pi = 3.14; double e = 2.71; qSwap(pi, e); // pi == 2.71, e == 3.14Use
std::upper_bound
instead.Performs a binary search of the range [
begin
,end
) and returns the position of the one-past-the-last occurrence ofvalue
. If no such item is found, returns the position where the item should be inserted.The items in the range [
begin
, end ) must be sorted in ascending order; seeqSort()
.Example:
QList<int> list; list << 3 << 3 << 6 << 6 << 6 << 8; QList<int>::iterator i = qUpperBound(list.begin(), list.end(), 5); list.insert(i, 5); // list: [ 3, 3, 5, 6, 6, 6, 8 ] i = qUpperBound(list.begin(), list.end(), 12); list.insert(i, 12); // list: [ 3, 3, 5, 6, 6, 6, 8, 12 ]This function requires the item type (in the example above,
int
) to implementoperator<()
.can be used in conjunction with
qLowerBound()
to iterate over all occurrences of the same value:QVector<int> vect; vect << 3 << 3 << 6 << 6 << 6 << 8; QVector<int>::iterator begin6 = qLowerBound(vect.begin(), vect.end(), 6); QVector<int>::iterator end6 = qUpperBound(vect.begin(), vect.end(), 6); QVector<int>::iterator i = begin6; while (i != end6) { *i = 7; ++i; } // vect: [ 3, 3, 7, 7, 7, 8 ]See also
qLowerBound()
qBinaryFind()
This is an overloaded function.
Use
std::upper_bound
instead.Uses the
lessThan
function instead ofoperator<()
to compare the items.Note that the items in the range must be sorted according to the order specified by the
lessThan
object.This is an overloaded function.
Use
std::upper_bound
instead.This is the same as
qUpperBound
(container
.begin(),container
.end(),value
);
© 2022 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.