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 deleteon 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, andQHashclasses.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, ifConstIteratoris 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_tablearray and return the corresponding Unicode value from thevalue_tableif 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 += nadvances iterator
ibynpositions
i -= nmoves iterator
iback bynpositions
i + norn + ireturns the iterator for the item
npositions ahead of iteratori
i - nreturns the iterator for the item
npositions behind of iteratori
i - jreturns the number of items between iterators
iandj
i[n]same as
*(i + n)
i < jreturns
trueif iteratorjcomes after iteratori
QListandQVector‘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_searchorstd::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::greaterThe 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_searchorstd::lower_boundinstead.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_searchorstd::lower_boundinstead.Uses the
lessThanfunction instead ofoperator<()to compare the items.Note that the items in the range must be sorted according to the order specified by the
lessThanobject.This is an overloaded function.
Use
std::binary_searchorstd::lower_boundinstead.This is the same as
qBinaryFind(container.begin(),container.end(),value);Use
std::copyinstead.Copies the items from range [
begin1,end1) to range [begin2, …), in the order in which they appear.The item at position
begin1is 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_backwardinstead.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::countinstead.Returns the number of occurrences of
valuein the range [begin,end), which is returned inn.nis 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::countinstead.Instead of operating on iterators, as in the other overload, this function operates on the specified
containerto obtain the number of instances ofvaluein 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++deleteoperator. 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
deleteon 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
QMapandQHash. 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::equalinstead.Compares the items in the range [
begin1,end1) with the items in the range [begin2, …). Returnstrueif 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::fillinstead.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::fillinstead.This is the same as
qFill(container.begin(),container.end(),value);Use
std::findinstead.Returns an iterator to the first occurrence of
valuein a container in the range [begin,end). Returnsendifvalueisn’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::findinstead.This is the same as
qFind(container.constBegin(),container.constEnd(),value);Use
std::greaterinstead.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
qLessUse
std::lessinstead.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
qGreaterUse
std::lower_boundinstead.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_boundinstead.Uses the
lessThanfunction instead ofoperator<()to compare the items.Note that the items in the range must be sorted according to the order specified by the
lessThanobject.This is an overloaded function.
Use
std::lower_boundinstead.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::sortinstead.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::sortinstead.Uses the
lessThanfunction instead ofoperator<()to compare the items.For example, here’s how to sort the strings in a
QStringListin 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
qGreateras thelessThanparameter. 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 theQMapkey. This is often more convenient than defining alessThanfunction. 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
QMapThis is an overloaded function.
Use
std::sortinstead.This is the same as
qSort(container.begin(),container.end());Use
std::stable_sortinstead.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_sortinstead.Uses the
lessThanfunction instead ofoperator<()to compare the items.For example, here’s how to sort the strings in a
QStringListin 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
qGreateras thelessThanparameter. 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_sortinstead.This is the same as
qStableSort(container.begin(),container.end());Use
std::swapinstead.Exchanges the values of variables
var1andvar2.Example:
double pi = 3.14; double e = 2.71; qSwap(pi, e); // pi == 2.71, e == 3.14Use
std::upper_boundinstead.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_boundinstead.Uses the
lessThanfunction instead ofoperator<()to compare the items.Note that the items in the range must be sorted according to the order specified by the
lessThanobject.This is an overloaded function.
Use
std::upper_boundinstead.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.