Namespaces
Variants

std::ranges::begin

С ru.cppreference.net
 
 
Библиотека диапазонов
Адаптеры диапазонов
 
Определён в заголовочном файле <ranges>
Определён в заголовочном файле <iterator>
inline namespace /* unspecified */ {
    inline constexpr /* unspecified */ begin = /* unspecified */;
}
(начиная с C++20)
(объект точки настройки)
Сигнатура вызова
template< class T >
    requires /* see below */
constexpr std::input_or_output_iterator auto begin( T&& t );
(начиная с C++20)

Возвращает итератор на первый элемент аргумента.

Если аргумент является lvalue или ranges::enable_borrowed_range<std::remove_cv_t<T>> является true, то вызов ranges::begin является эквивалентным выражению:

  1. t + 0 если t имеет тип массива.
    • Если std::remove_all_extents_t<std::remove_reference_t<T>> является неполным, то вызов ranges::begin является ошибочным, диагностика не требуется.
  2. В противном случае, decay-copy(t.begin())(до C++23)auto(t.begin())(начиная с C++23), если это выражение допустимо и его тип моделирует std::input_or_output_iterator.
  3. В противном случае, decay-copy(begin(t))(до C++23)auto(begin(t))(начиная с C++23), если T является типом класса или перечисления, это выражение допустимо и его тип моделирует std::input_or_output_iterator, где значение begin устанавливается как при выполнении поиска, зависящего от аргументов только.

Во всех остальных случаях вызов ranges::begin является ошибочным, что может привести к ошибке подстановки когда вызов появляется в непосредственном контексте инстанцирования шаблона.

Объекты точек кастомизации

Имя ranges::begin обозначает объект точки кастомизации , который является константным функциональным объектом типа литерального semiregular класса. Для подробностей см. CustomizationPointObject .

Примечания

Если аргумент является rvalue (т.е. T является объектным типом) и ranges:: enable_borrowed_range < std:: remove_cv_t < T >> равно false , вызов ranges::begin является некорректным, что также приводит к ошибке подстановки.

Возвращаемый тип моделирует std::input_or_output_iterator во всех случаях.

Стандарт C++20 требует, чтобы если базовый вызов функции begin возвращает prvalue, возвращаемое значение создавалось перемещением из материализованного временного объекта. Все реализации напрямую возвращают prvalue вместо этого. Требование исправлено пост-C++20 предложением P0849R8 для соответствия реализациям.

Пример

#include <cassert>
#include <ranges>
#include <vector>
int main() 
{
    std::vector v{3, 1, 4};
    auto vi = std::ranges::begin(v);
    auto vci = std::ranges::cbegin(v);
    assert(*vi == 3 and *vi == *vci);
    ++vi;
    ++vci; // OK: vci является изменяемым объектом
    *vi = 42; // OK: vi указывает на изменяемый элемент
    // *vci = 13; // Ошибка: vci указывает на неизменяемый элемент
    int a[]{-5, 10, 15};
    auto ai = std::ranges::begin(a); // работает и с C-массивами
    assert(*ai == -5);
    *ai = 42; // OK
}

Отчеты о дефектах

Следующие отчеты о дефектах, изменяющих поведение, были применены ретроактивно к ранее опубликованным стандартам C++.

DR Применяется к Поведение как опубликовано Корректное поведение
P2602R2 C++20 существует механизм для запрета определенных не-членов begin найденных через ADL удален такой механизм

Смотрите также

возвращает итератор на начало диапазона только для чтения
(объект точки кастомизации)
(C++11) (C++14)
возвращает итератор на начало контейнера или массива
(шаблон функции)