9.2.3. Функции-члены begin() и end()
Функции-члены begin() и end() (см. раздел 3.4.1) возвращают итераторы на первый и следующий после последнего элементы контейнера соответственно. Эти итераторы, как правило, используют при создании диапазона итераторов, охватывающего все элементы контейнера.
Как показано в табл. 9.2, есть несколько версий этих функций: имена которых начинаются с буквы r возвращают реверсивные итераторы (рассматриваются в разделе 10.4.3), а с буквы c — возвращают константную версию соответствующего итератора:
list<string> a = {"Milton", "Shakespeare", "Austen"};
auto it1 = a.begin(); // list<string>::iterator
auto it2 = a.rbegin(); // list<string>::reverse_iterator
auto it3 = a.cbegin(); // list<string>::const_iterator
auto it4 = a.crbegin();// list<string>::const_reverse_iterator
Функции, имена которых не начинаются с буквы c, перегружены. Таким образом, фактически есть две функции-члена begin(). Одна является константной (см. раздел 7.1.2) и возвращает тип const_iterator контейнера. Вторая не константна и возвращает тип iterator контейнера. Аналогично для функций rbegin(), end() и rend(). При вызове такой функции-члена для неконстантного объекта используется версия, возвращающая тип iterator. Константная версия итераторов будет получена только при вызове этих функций для константного объекта. Подобно указателям и ссылкам на константу, итератор типа iterator можно преобразовать в соответствующий итератор типа const_iterator, но не наоборот.
Версии этих функций, имена которых не начинаются с буквы с, были введены согласно новому стандарту для обеспечения использования ключевого слова auto с функциями begin() и end() (см. раздел 2.5.2). Прежде не было никакого иного выхода, кроме как явно указать необходимый тип итератора:
// тип указан явно
list<string>::iterator it5 = a.begin();
list<string>::const_iterator it6 = a.begin();
// iterator или const_iterator в зависимости от типа а
auto it7 = a.begin(); // const_iterator только если a константа
auto it8 = a.cbegin(); // it8 - const_iterator
Когда с функциями begin() или end() используется ключевое слово auto, тип возвращаемого итератора зависит от типа контейнера. То, как предполагается использовать итератор, несущественно. Версии c позволяют получать итератор типа const_iterator независимо от типа контейнера.
Когда доступ на запись не нужен, используйте версии cbegin() и cend().
Упражнения раздела 9.2.3
Упражнение 9.9. В чем разница между функциями begin() и cbegin()?
Упражнение 9.10. Каковы типы следующих четырех объектов?
vector<int> v1;
const vector<int> v2;
auto it1 = v1.begin(), it2 = v2.begin();
auto it3 = v1.cbegin(), it4 = v2.cbegin();
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОК