for (auto it = s.begin(); it != s.end() && !isspace(*it); ++it)
*it = toupper(*it); //
Этот цикл, подобно таковому в разделе 3.2.3, перебирает символы строки s
, останавливаясь, когда встречается пробел. Но данный цикл использует для этого итератор, а не индексирование.
Цикл начинается с инициализации итератора it
результатом вызова функции s.begin()
, чтобы он указывал на первый символ строки s
(если он есть). Условие проверяет, не достиг ли итератор it
конца строки (s.end()
). Если это не так, то проверяется следующее условие, где обращение к значению итератора it
, возвращающее текущий символ, передается функции isspace()
, чтобы выяснить, не пробел ли это. В конце каждой итерации выполняется оператор ++it
, чтобы переместить итератор на следующий символ строки s
.
У этого цикла то же тело, что и у последнего оператора if
предыдущей программы. Обращение к значению итератора it
используется и для передачи текущего символа функции toupper()
, и для присвоения полученного результата символу, на который указывает итератор it
.
Программисты, перешедшие на язык С++ с языка С или Java, могли бы быть удивлены тем, что в данном цикле for
был использован оператор !=
, а не <
. Программисты С++ используют оператор !=
исключительно по привычке. По этой же причине они используют итераторы, а не индексирование: этот стиль программирования одинаково хорошо применим к контейнерам различных видов, предоставляемых библиотекой.
Как уже упоминалось, только у некоторых библиотечных типов, vector
и string
, есть оператор индексирования. Тем не менее у всех библиотечных контейнеров есть итераторы, для которых определены операторы ==
и !=
. Однако большинство их итераторов не имеют оператора <
. При обычном использовании итераторов и оператора !=
можно не заботиться о точном типе обрабатываемого контейнера.
Подобно тому, как не всегда известен точный тип size_type
элемента вектора или строки (см. раздел 3.2.2), мы обычно не знаем (да и не обязаны знать) точный тип итератора. Как и в случае с типом size_type
, библиотечные типы, у которых есть итераторы, определяют типы по имени iterator
и const_iterator
, которые представляют фактические типы итераторов.
vector
//
string::iterator it2; //
//
vector
//
string::const_iterator it4; //
//
Тип const_iterator
ведет себя как константный указатель (см. раздел 2.4.2). Как и константный указатель, тип const_iterator
позволяет читать, но не писать в элемент, на который он указывает; объект типа iterator
позволяет и читать, и записывать. Если вектор или строка являются константой, можно использовать итератор только типа const_iterator
. Если вектор или строка на являются константой, можно использовать итератор и типа iterator
, и типа const_iterator
.