Namespaces
Variants

std::ranges:: end

From cppreference.net
Ranges library
Range adaptors
Определено в заголовке <ranges>
Определено в заголовке <iterator>
inline namespace /* unspecified */ {

inline constexpr /* unspecified */ end = /* unspecified */ ;

}
(since C++20)
(объект точки кастомизации)
Сигнатура вызова
template < class T >

requires /* see below */

constexpr std:: sentinel_for < ranges:: iterator_t < T >> auto end ( T && t ) ;
(since 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 имеет тип массива с известной границей.
  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)
возвращает итератор на конец контейнера или массива
(шаблон функции)