Namespaces
Variants

std::ranges::end

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

Возвращает ограничитель, указывающий конец диапазона.

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

  1. t + std::extent_v<T> если t имеет тип массива известного размера.
  2. В противном случае, decay-copy(t.end())(до C++23)auto(t.end())(начиная с C++23), если это выражение допустимо и его тип моделирует std::sentinel_for<ranges::iterator_t<T>>.
  3. В противном случае, decay-copy(end(t))(до C++23)auto(end(t))(начиная с C++23), если T является типом класса или перечисления, это выражение допустимо и его преобразованный тип моделирует std::sentinel_for<ranges::iterator_t<T>>, причём значение end устанавливается так, как если бы выполнялся поиск, зависящий от аргументов только.

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

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

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

Примечания

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

Если ranges :: end ( std:: forward < T > ( t ) ) корректен, тогда decltype ( ranges :: end ( std:: forward < T > ( t ) ) ) и decltype ( ranges:: begin ( std:: forward < T > ( t ) ) ) моделируют std::sentinel_for во всех случаях, тогда как T моделирует std::ranges::range .

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

Пример

#include <algorithm>
#include <iostream>
#include <ranges>
#include <vector>
int main()
{
    std::vector<int> vec{3, 1, 4};
    if (std::ranges::find(vec, 5) != std::ranges::end(vec))
        std::cout << "found a 5 in vector vec!\n";
    int arr[]{5, 10, 15};
    if (std::ranges::find(arr, 5) != std::ranges::end(arr))
        std::cout << "found a 5 in array arr!\n";
}

Вывод:

found a 5 in array arr!

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

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

DR Applied to Behavior as published Correct behavior
P2602R2 C++20 there's machinery to prohibit certain non-member end found by ADL removed such machinery

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

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