Что делают функции begin() и end()
Шаблоны функций std::begin и std::end просто вызывают методы begin() и end() у своего аргумента и возвращают полученный результат. Но при этом они специализированы особым образом для аргументов типа «массив»: std::begin возвращает указатель на начало массива, а std::end указатель на воображаемый элемент за концом массива.
Эти функции предназначены для унификации интерфейса между стандартными контейнерами, обыкновенными массивами и std::initializer_list . Начиная с С++17 в этот комплект также входят шаблоны функции std::data , std::size и std::empty , служащие аналогичным целям и реализованные аналогичным образом.
Пользуясь этими функциями вы можете писать унифицированный generic шаблонный код, который сможет работать как со стандартными контейнерами, так и с обычными массивами, и с std::initializer_list без необходимости вручную писать специализированные версии для этих особых случаев
За пределами generic кода необходимости в использовании этих функций нет, но использовать их по-прежнему можно и иногда даже весьма удобно.
std:: begin
Returns an iterator pointing to the first element in the sequence:
(1) Container The function returns cont.begin() . (2) Array The function returns the array-to-pointer conversion of its argument.
If the sequence is empty, the returned value shall not be dereferenced.
These function templates are defined in multiple headers: Each of these headers includes the generic templates for all container and array types and not simply a specific overload. The headers are: <iterator> , <array> , <deque> , <forward_list> , <list> , map , <regex> , <set> , <string> , <unordered_map> , <unordered_set> and <vector> .
Conversely, begin is overloaded (with a different definition) in headers <initializer_list> and <valarray> .
std:: begin, std:: cbegin
Returns an iterator to the beginning of the given range.
Contents
[edit] Parameters
| c | — | a container or view with a begin member function |
| array | — | an array of arbitrary type |
[edit] Return value
An iterator to the beginning of the range.
[edit] Exceptions
[edit] Overloads
Custom overloads of begin may be provided for classes and enumerations that do not expose a suitable begin() member function, yet can be iterated. The following overloads are already provided by the standard library:
Similar to the use of swap (described in Swappable ), typical use of the begin function in generic context is an equivalent of using std :: begin ; begin ( arg ) ; , which allows both the ADL-selected overloads for user-defined types and the standard library function templates to appear in the same overload set.
Overloads of begin found by argument-dependent lookup can be used to customize the behavior of std :: ranges:: begin , std :: ranges:: cbegin , and other customization pointer objects depending on std :: ranges:: begin .
[edit] Notes
(1,3) exactly reflect the behavior of C :: begin ( ) . Their effects may be surprising if the member function does not have a reasonable implementation.
std::cbegin is introduced for unification of member and non-member range accesses. See also LWG issue 2128.
If C is a shallow-const view, std::cbegin may return a mutable iterator. Such behavior is unexpected for some users. See also P2276 and P2278.
Begin c что это
Итераторы обеспечивают доступ к элементам контейнера. С помощью итераторов очень удобно перебирать элементы. Итератор описывается типом iterator . Но для каждого контейнера конкретный тип итератора будет отличаться. Так, итератор для контейнера list<int> представляет тип list<int>::iterator , а итератор контейнера vector<int> представляет тип vector<int>::iterator и так далее.
Для получения итераторов контейнеры в C++ обладают такими функциями, как begin() и end() . Функция begin() возвращает итератор, который указывает на первый элемент контейнера (при наличии в контейнере элементов). Функция end() возвращает итератор, который указывает на следующую позицию после последнего элемента, то есть по сути на конец контейнера. Если контейнер пуст, то итераторы, возвращаемые обоими методами begin и end совпадают. Если итератор begin не равен итератору end, то между ними есть как минимум один элемент.
Обе этих функции возвращают итератор для конкретного типа контейнера:
В данном случае создается вектор — контейнер типа vector, который содержит значения типа int. И этот контейнер инициализируется набором <1, 2, 3, 4>. И через метод begin() можно получить итератор для этого контейнера. Причем этот итератор будет указывать на первый элемент контейнера.
Операции с итераторами
С итераторами можно проводить следующие операции:
*iter : получение элемента, на который указывает итератор
++iter : перемещение итератора вперед для обращения к следующему элементу
—iter : перемещение итератора назад для обращения к предыдущему элементу. Итераторы контейнера forward_list не поддерживают операцию декремента.
iter1 == iter2 : два итератора равны, если они указывают на один и тот же элемент
iter1 != iter2 : два итератора не равны, если они указывают на разные элементы
Например, используем итераторы для перебора элементов вектора:
При работе с контейнерами следует учитывать, что добавление или удаление элементов в контейнере может привести к тому, что все текущие итераторы для данного контейнера, а также ссылки и указатели на его элементы станут недопустимыми.
Итераторы позволяют не только получать элементы, но и изменять их:
В данном случае в цикле while элементы вектора возводятся в квадрат. Консольный вывод данной программы:
Константные итераторы
Если контейнер представляет константу, то для обращения к элементам этого контейнера можно использовать только константный итератор (тип const_iterator ). Такой итератор позволяет считывать элементы, но не изменять их:
Для получения константного итератора также можно использовать функции cbegin() и cend . При этом даже если контейнер не представляет константу, но при этом для его перебора используется константный итератор, то опять же нельзя изменять значения элементов этого контейнера:
Реверсивные итераторы
Реверсивные итераторы позволяют перебирать элементы контейнера в обратном направлении. Для получения реверсивного итератора применяются функции rbegin() и rend() , а сам итератор представляет тип :
Консольный вывод программы:
Если надо обеспечить защиту от изменения значений контейнера, то можно использовать константный реверсивный итератор, который представлен типом const_reverse_iterator и который можно получить с помощью функций crbegin() и crend() :
Также итераторы для всех типов, кроме list и forward_list, поддерживают ряд дополнительных операций:
iter + n : возвращает итератор, который смещен от итератора iter на n позиций вперед
iter — n : возвращает итератор, который смещен от итератора iter на n позиций назад
iter += n : перемещает итератор на n позиций вперед
iter -= n : перемещает итератор на n позиций назад
iter1 — iter2 : возвращает количество позиций между итераторами iter1 и iter2
>, >=, <, <= : операции сравнения. Один итератор больше другого, если указывает на элемент, который ближе к концу