Spec-Zone.ru › C++

std::ranges::rbegin

Определено в заголовке <ranges>
Определено в заголовке <iterator>
inline namespace /* unspecified */ {
    inline constexpr /* unspecified */ rbegin = /* unspecified */;
}
(с C++20)
(объект точки кастомизации)
Подпись вызова
template< class T >
    requires /* see below */
constexpr std::input_or_output_iterator auto rbegin( T&& t );
(с C++20)

Возвращает итератор к последнему элементу аргумента.

range-rbegin-rend.svg

Если T - тип массива, и std::remove_all_extents_t<std::remove_reference_t<T>> неполный, то вызов ranges::rbegin некорректен, диагностика не требуется.

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

  1. decay-copy(t.rbegin())(до C++23)auto(t.rbegin())(с C++23), если это выражение корректно и его тип удовлетворяет std::input_or_output_iterator.
  2. В противном случае, decay-copy(rbegin(t))(до C++23)auto(rbegin(t))(с C++23), если T является классом или перечислением, это выражение корректно и его тип удовлетворяет std::input_or_output_iterator, где смысл rbegin устанавливается как если бы выполнялся поиск зависимых от аргументов только.
  3. В противном случае, std::make_reverse_iterator(ranges::end(t)) если ranges::begin(t) и ranges::end(t) — корректные выражения, имеющие одинаковый тип и удовлетворяющие std::bidirectional_iterator.

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

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

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

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

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

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

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

Примечания

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

Тип возврата во всех случаях удовлетворяет std::input_or_output_iterator.

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

Пример

#include <iostream>
#include <ranges>
#include <span>
#include <vector>
 
int main()
{
    std::vector<int> v = {3, 1, 4};
    auto vi = std::ranges::rbegin(v);
    std::cout << *vi << '\n';
    *vi = 42; // OK
 
    int a[] = {-5, 10, 15};
    auto ai = std::ranges::rbegin(a);
    std::cout << *ai << '\n';
    *ai = 42; // OK
 
    // auto x_x = std::ranges::rbegin(std::vector{6, 6, 6});
    // ill-formed: the argument is an rvalue (see Notes ↑)
 
    auto si = std::ranges::rbegin(std::span{a}); // OK
    static_assert(std::ranges::enable_borrowed_range<
        std::remove_cv_t<decltype(std::span{a})>>);
    *si = 42; // OK
}

Вывод:

4
15

Отчеты об ошибках

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

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

См. также

ranges::crbegin
(C++20)
возвращает обратный итератор к только для чтения диапазону
(объект точки кастомизации)
rbegincrbegin
(C++14)
возвращает обратный итератор к началу контейнера или массива
(функция-шаблон)

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

Spec-Zone.ru

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