<QtAlgorithms> - Универсальные алгоритмы
В заголовочном файле <QtAlgorithms> содержатся универсальные алгоритмы, основанные на шаблонах. Подробнее...
| Заголовок: | #include <QtAlgorithms> |
Функции
| uint | qCountLeadingZeroBits(quint32 v) |
| uint | qCountLeadingZeroBits(quint8 v) |
| uint | qCountLeadingZeroBits(quint16 v) |
| uint | qCountLeadingZeroBits(quint64 v) |
| uint | qCountTrailingZeroBits(quint8 v) |
| uint | qCountTrailingZeroBits(quint32 v) |
| uint | qCountTrailingZeroBits(quint16 v) |
| uint | qCountTrailingZeroBits(quint64 v) |
| void | qDeleteAll(ForwardIterator begin, ForwardIterator end) |
| void | qDeleteAll(const Container &c) |
| uint | qPopulationCount(quint8 v) |
| uint | qPopulationCount(quint32 v) |
| uint | qPopulationCount(quint16 v) |
| uint | qPopulationCount(quint64 v) |
Подробное описание
Qt предоставляет ряд глобальных шаблонных функций в <QtAlgorithms>, которые работают с контейнерами и выполняют небольшие задачи, чтобы упростить работу, например, qDeleteAll(), которая вызывает operator delete для всех элементов в заданном контейнере или диапазоне. Вы можете использовать эти алгоритмы с любым классом контейнера, который предоставляет итераторы в стиле STL, включая Qt's QList, QLinkedList, QVector, QMap и QHash классы.
Большинство алгоритмов принимают итераторы в стиле STL в качестве параметров. Алгоритмы являются универсальными в том смысле, что они не привязаны к конкретному классу итераторов; вы можете использовать их с любыми итераторами, которые удовлетворяют определённому набору требований.
Различные алгоритмы могут иметь различные требования к итераторам, которые они принимают. Например, qFill() принимает два итератора вперёд. Типы итераторов, необходимые для каждого алгоритма, указаны для каждого алгоритма. Если передаётся итератор неверного типа (например, если QList::ConstIterator передаётся как итератор вывода), вы всегда получите ошибку компилятора, хотя и не обязательно очень информативную.
Некоторые алгоритмы имеют особые требования к типу значения, хранящегося в контейнерах. Например, qDeleteAll() требует, чтобы тип значения был типом указателя без const (например, QWidget *). Требования к типу значения указаны для каждого алгоритма, и компилятор выдаст ошибку, если требование не будет выполнено.
Универсальные алгоритмы могут быть использованы с другими классами контейнеров, кроме тех, которые предоставляются Qt и STL. Синтаксис итераторов в стиле STL моделируется по образцу указателей C++, поэтому можно использовать обычные массивы как контейнеры и обычные указатели как итераторы. Распространённый приём — использовать qBinaryFind() вместе с двумя статическими массивами: один, содержащий список ключей, и другой, содержащий список связанных значений. Например, следующий код ищет HTML-сущность (например, &) в массиве name_table и возвращает соответствующее значение Unicode из массива value_table если сущность распознана:
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]);
} Этот вид кода предназначен только для опытных пользователей; для большинства приложений подход на основе QMap или QHash будет работать так же хорошо:
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));
} Типы итераторов
Алгоритмы имеют определённые требования к типам итераторов, которые они принимают, и эти требования указываются индивидуально для каждой функции. Компилятор выдаст ошибку, если требование не будет выполнено.
Итераторы входных данных
Итератор входных данных — это итератор, который может использоваться для последовательного чтения данных из контейнера. Он должен предоставлять следующие операторы: == и != для сравнения двух итераторов, унарный * для получения значения, хранящегося в элементе, и префиксный ++ для перехода к следующему элементу.
Типы итераторов контейнеров Qt (const и не-const) являются итераторами входных данных.
Итераторы вывода
Итератор вывода — это итератор, который может использоваться для последовательной записи данных в контейнер или в поток вывода. Он должен предоставлять следующие операторы: унарный * для записи значения (т.е., *it = val) и префиксный ++ для перехода к следующему элементу.
Типы итераторов контейнеров Qt (не-const) являются итераторами вывода.
Итераторы вперёд
Итератор вперёд — это итератор, который удовлетворяет требованиям как итераторов входных данных, так и итераторов вывода.
Типы итераторов контейнеров Qt (не-const) являются итераторами вперёд.
Двунаправленные итераторы
Двунаправленный итератор — это итератор, который удовлетворяет требованиям итераторов вперёд, но кроме того поддерживает префиксный -- для перехода назад.
Типы итераторов контейнеров Qt (не-const) являются двунаправленными итераторами.
Итераторы произвольного доступа
Последняя категория, итераторы произвольного доступа, является самой мощной категорией итераторов. Она поддерживает все требования двунаправленного итератора и поддерживает следующие операции:
i += n |
перемещает итератор i на n позиций вперёд |
i -= n |
перемещает итератор i на n позиций назад |
i + n или n + i
|
возвращает итератор для элемента n позиций вперёд от итератора i
|
i - n |
возвращает итератор для элемента n позиций назад от итератора i
|
i - j |
возвращает количество элементов между итераторами i и j
|
i[n] |
то же, что и *(i + n)
|
i < j |
возвращает true если итератор j находится после итератора i
|
QList и QVector типы не-const итераторов являются итераторами произвольного доступа.
Qt и алгоритмы STL
Исторически Qt предоставлял функции, которые были прямыми эквивалентами многих алгоритмических функций STL. Начиная с Qt 5.0, вам вместо этого рекомендуется использовать непосредственно реализации, доступные в STL; большинство функций Qt устарели (хотя они по-прежнему доступны для сохранения компиляции старого кода).
Рекомендации по переносу
В большинстве случаев приложение, использующее устаревшие алгоритмические функции Qt, может быть легко перенесено на использование эквивалентных функций STL. Вам нужно:
- добавить директиву препроцессора
#include <algorithm>; - заменить функции Qt эквивалентами STL в соответствии со следующей таблицей.
| Функция Qt | Функция STL |
|---|---|
| qBinaryFind |
std::binary_search или std::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 |
Единственные случаи, когда порт может быть не очевиден, — это если старый код полагался на шаблонные специализации функций qLess() и/или qSwap(), которые использовались внутри реализаций функций Qt для алгоритмов, но вместо этого игнорируются STL-функциями.
В случае, если старый код полагался на специализацию функционального объекта qLess(), то обходным путем является явное указание экземпляра класса qLess() в STL-функцию, например, так:
std::sort(container.begin(), container.end(), qLess<T>());
Вместо этого, поскольку невозможно передать пользовательский функциональный объект-обменник в STL-функции, единственным обходным путем для шаблонной специализации для qSwap() является предоставление той же специализации для std::swap().
См. также классы контейнеров и <QtGlobal>.
Документация функций
uint qCountLeadingZeroBits(quint32 v)
Возвращает количество последовательных нулевых битов в v при поиске с старшего значащего бита. Например, qCountLeadingZeroBits(quint32(1)) возвращает 31, а qCountLeadingZeroBits(quint32(8)) возвращает 28.
Эта функция была добавлена в Qt 5.6.
uint qCountLeadingZeroBits(quint8 v)
Возвращает количество последовательных нулевых битов в v при поиске с старшего значащего бита. Например, qCountLeadingZeroBits(quint8(1)) возвращает 7, а qCountLeadingZeroBits(quint8(8)) возвращает 4.
Эта функция была добавлена в Qt 5.6.
uint qCountLeadingZeroBits(quint16 v)
Возвращает количество последовательных нулевых битов в v при поиске с старшего значащего бита. Например, qCountLeadingZeroBits(quint16(1)) возвращает 15, а qCountLeadingZeroBits(quint16(8)) возвращает 12.
Эта функция была добавлена в Qt 5.6.
uint qCountLeadingZeroBits(quint64 v)
Возвращает количество последовательных нулевых битов в v при поиске с старшего значащего бита. Например, qCountLeadingZeroBits(quint64(1)) возвращает 63, а qCountLeadingZeroBits(quint64(8)) возвращает 60.
Эта функция была добавлена в Qt 5.6.
uint qCountTrailingZeroBits(quint8 v)
Возвращает количество последовательных нулевых битов в v при поиске с младшего значащего бита. Например, qCountTrailingZeroBits(1) возвращает 0, а qCountTrailingZeroBits(8) возвращает 3.
Эта функция была добавлена в Qt 5.6.
uint qCountTrailingZeroBits(quint32 v)
Это перегруженная функция.
Эта функция была добавлена в Qt 5.6.
uint qCountTrailingZeroBits(quint16 v)
Это перегруженная функция.
Эта функция была добавлена в Qt 5.6.
uint qCountTrailingZeroBits(quint64 v)
Это перегруженная функция.
Эта функция была добавлена в Qt 5.6.
void qDeleteAll(ForwardIterator begin, ForwardIterator end)
Удаляет все элементы в диапазоне [begin, end) с помощью оператора C++ delete. Тип элемента должен быть указателем (например, QWidget *).
Пример:
QList<Employee *> list;
list.append(new Employee("Blackpool", "Stephen"));
list.append(new Employee("Twist", "Oliver"));
qDeleteAll(list.begin(), list.end());
list.clear(); Обратите внимание, что qDeleteAll() не удаляет элементы из контейнера; она просто вызывает delete на них. В примере выше мы вызываем clear() для контейнера, чтобы удалить элементы.
Эта функция также может быть использована для удаления элементов, хранящихся в ассоциативных контейнерах, таких как QMap и QHash. Функцией будут удалены только объекты, хранящиеся в каждом контейнере; объекты, используемые в качестве ключей, не будут удалены.
См. также итераторы с направленным доступом.
void qDeleteAll(const Container &c)
Это перегруженная функция.
Это то же самое, что qDeleteAll(c.begin(), c.end()).
uint qPopulationCount(quint8 v)
Возвращает количество установленных битов в v. Это число также называется весом Хэмминга v.
Эта функция была добавлена в Qt 5.2.
uint qPopulationCount(quint32 v)
Это перегруженная функция.
Эта функция была добавлена в Qt 5.2.
uint qPopulationCount(quint16 v)
Это перегруженная функция.
Эта функция была добавлена в Qt 5.2.
uint qPopulationCount(quint64 v)
Это перегруженная функция.
Эта функция была добавлена в Qt 5.2.
© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-5.14/qtalgorithms.html