Итераторы в стиле STL также имеют функции key
и value. Для неконстантных типов итераторов value возвращает неконстантную ссылку, позволяя нам изменять значение в ходе просмотра контейнера. Следует отметить, что хотя эти итераторы называются итераторами «в стиле STL», они существенно отличаются от итераторов STL контейнера map, которые ссылаются на pair.Оператор цикла foreach
также работает с ассоциативными контейнерами, но только с компонентом значение пар ключ—значение. Если нужны как ключи, так и значение, мы можем вызвать функции keys и values(const К &) во внутреннем цикле foreach:QMultiMap map;
…
foreach (QString key, map.keys) {
foreach (int value, map.values(key)) {
do_something(key, value);
}
}
Обобщенные алгоритмы
В заголовочном файле
объявляются глобальные шаблонные функции, которые реализуют основные алгоритмы для контейнеров. Большинство этих функций работают с итераторами в стиле STL.Заголовочный файл STL
содержит более полный набор обобщенных алгоритмов. Эти алгоритмы могут использоваться не только с STL-контейнерами, но и с Qt—контейнерами. Если STL доступен на всех ваших платформах, вероятно, нет причин не использовать STL—алгоритмы, когда в Qt отсутствует эквивалентный алгоритм. Далее мы кратко рассмотрим наиболее важные Qt—алгоритмы.Алгоритм qFind
выполняет поиск конкретного значения в контейнере. Он принимает «начальный» и «конечный» итераторы и возвращает итератор, ссылающийся на первый подходящий элемент, или «конечный» итератор, если нет подходящих элементов. В представленном ниже примере i устанавливается на list.begin + 1, a j устанавливается на list.end.QStringList list;
list << "Emma" << "Karl" << "James" << "Mariette";
QStringList::iterator i = qFind(list.begin, list.end, "Karl");
QStringList::iterator j = qFind(list.begin, list.end, "Petra");
Алгоритм qBinaryFind
выполняет поиск подобно алгоритму qFind, за исключением того, что он предполагает упорядоченность элементов в возрастающем порядке и использует двоичный поиск в отличие от линейного поиска в qFind. Алгоритм qFill
заполняет контейнер конкретным значением:QLinkedList list(10);
qFill(list.begin, list.end, 1009);
Как и другие алгоритмы, основанные на применении итераторов, qFill
может выполняться для части контейнера, если соответствующим образом установить аргументы. В следующем фрагменте программного кода первые пять элементов вектора инициализируются значением 1009, а последние пять элементов — значением 2013:QVector vect(10);
qFill(vect.begin, vect.begin + 5, 1009);
qFill(vect.end - 5, vect.end, 2013);
Алгоритм qCopy
копирует значения одного контейнера в другой.QVector vect(list.count);
qCopy(list.begin, list.end, vect.begin);
Алгоритм qCopy
может также использоваться для копирования элементов в рамках одного контейнера, если исходный диапазон и целевой диапазон не перекрываются. В следующем фрагменте программного кода мы заменяем последние два элемента списка первыми двумя элементами:qCopy(list.begin, list.begin + 2, list.end - 2);
Алгоритм qSort
сортирует элементы контейнера в порядке их возрастания.qSort(list.begin, list.end);
По умолчанию qSort
использует оператор < для сравнения элементов. Для сортировки элементов по убыванию передайте qGreater в качестве третьего аргумента (здесь T — тип элемента контейнера):qSort(list.begin, list.end, qGreater);
Мы можем использовать третий параметр для определения пользовательского критерия сортировки. Например, ниже приводится функция сравнения «меньше, чем», которая выполняет сравнение строк QString
без учета регистра:bool insensitiveLessThan(const QString &str1, const QString &str2)
{
return str1.toLower < str2.toLower;
}
Тогда вызов qSort
будет таким: QStringList list;
qSort(list.begin, list.end, insensitiveLessThan);