Spec-Zone.ru › C++

std::ranges::size

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

Вычисляет количество элементов в t за константное время.

Вызов ranges::size эквивалентен:

  1. decay-copy(std::extent_v<T>)(до C++23)auto(std::extent_v<T>)(с C++23), если T — тип массива с известной границей.
  2. В противном случае, decay-copy(t.size())(до C++23)auto(t.size())(с C++23), если ranges::disable_sized_range<std::remove_cv_t<T>> является false, и выражение является корректным и имеет тип целого типа.
  3. В противном случае, decay-copy(size(t))(до C++23)auto(size(t))(с C++23), если ranges::disable_sized_range<std::remove_cv_t<T>> — false, и преобразованное выражение является корректным и имеет тип целого типа, где значение size устанавливается как при применении поиска зависимого от аргументов.
  4. В противном случае, /* to-unsigned-like */(ranges::end(t) - ranges::begin(t)), если T соответствует ranges::forward_range, а ranges::sentinel_t<T> соответствует std::sized_sentinel_for<ranges::iterator_t<T>>, где /* to-unsigned-like */ обозначает явное преобразование к типу целого беззнакового типа.

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

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

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

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

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

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

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

Примечания

Когда ranges::size(e) допустимо для выражения e, тип возвращаемого значения является целым типом.

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

Выражение ranges::distance(e) также может использоваться для определения размера диапазона e. В отличие от ranges::size(e), ranges::distance(e) работает даже если e является безразмерным диапазоном, ценой линейной сложности в этом случае.

Пример

#include <iostream>
#include <ranges>
#include <type_traits>
#include <vector>
 
int main()
{
    auto v = std::vector<int>{};
    std::cout << "ranges::size(v) == " << std::ranges::size(v) << '\n';
 
    auto il = {7};     // std::initializer_list
    std::cout << "ranges::size(il) == " << std::ranges::size(il) << '\n';
 
    int array[]{4, 5}; // array has a known bound
    std::cout << "ranges::size(array) == " << std::ranges::size(array) << '\n';
 
    static_assert(std::is_signed_v<decltype(std::ranges::size(v))> == false);
}

Вывод:

ranges::size(v) == 0
ranges::size(il) == 1
ranges::size(array) == 2

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

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

Отчет об ошибке Применено к Поведение, опубликованное Корректное поведение
P2602R2 C++20 существует механизм для запрета определенных не-членных функций size найденных с помощью ADL такой механизм удален

См. также

ranges::ssize
(C++20)
возвращает целое число со знаком, равное размеру диапазона
(объект точки кастомизации)
ranges::sized_range
(C++20)
задаёт диапазон, который знает свой размер за константное время
(концепция)
ranges::distance
(C++20)
возвращает расстояние между итератором и sentinels, или между началом и концом диапазона
(niebloid)
sizessize
(C++17)(C++20)
возвращает размер контейнера или массива
(шаблонная функция)

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

Spec-Zone.ru

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