Spec-Zone.ru › C++

std::ranges::end

Определено в заголовочном файле <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)

Возвращает страж, указывающий конец диапазона.

range-begin-end.svg

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

  1. t + std::extent_v<T> если t имеет тип массива с известной границей.
    • Если std::remove_all_extents_t<std::remove_reference_t<T>> неполна, то вызов ranges::end некорректен, не требуется диагностика.
  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 класса типов. Для целей пояснения, неквалифицированная версия его типа обозначается как __end_fn.

Все экземпляры __end_fn равны. Действия от вызова различных экземпляров типа __end_fn с одними и теми же аргументами эквивалентны, независимо от того, является ли выражение, обозначающее экземпляр, lvalue или rvalue, и квалифицирован ли он как const (однако экземпляр с квалификацией volatile не обязательно должен быть вызываемым). Таким образом, ranges::end можно свободно копировать, а его копии можно использовать взаимозаменяемо.

Учитывая набор типов Args..., если std::declval<Args>()... удовлетворяют требованиям к аргументам ranges::end выше, __end_fn моделирует

  • std::invocable<__end_fn, Args...>,
  • std::invocable<const __end_fn, Args...>,
  • std::invocable<__end_fn&, Args...>, и
  • std::invocable<const __end_fn&, Args...>.

В противном случае, ни один оператор вызова функции __end_fn не участвует в разрешении перегрузки.

Примечания

Если аргумент является 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, значение возврата было создано с помощью move-конструктора из материализованного временного объекта. Все реализации возвращают prvalue напрямую. Требование исправлено предложением P0849R8 после C++20, чтобы соответствовать реализациям.

Пример

#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 Применено к Поведение при публикации Корректное поведение
P2602R2 C++20 существует механизм для запрета определённых не-членных end , найденных с помощью ADL такой механизм удалён

См. также

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

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/ranges/end

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API