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 эквивалентен:
-
decay-copy(std::extent_v<T>)(до C++23)auto(std::extent_v<T>)(с C++23), еслиT— тип массива с известной границей. - В противном случае,
decay-copy(t.size())(до C++23)auto(t.size())(с C++23), еслиranges::disable_sized_range<std::remove_cv_t<T>>являетсяfalse, и выражение является корректным и имеет тип целого типа. - В противном случае,
decay-copy(size(t))(до C++23)auto(size(t))(с C++23), еслиranges::disable_sized_range<std::remove_cv_t<T>>—false, и преобразованное выражение является корректным и имеет тип целого типа, где значениеsizeустанавливается как при применении поиска зависимого от аргументов. - В противном случае,
/* 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 | такой механизм удален |
См. также
|
(C++20) | возвращает целое число со знаком, равное размеру диапазона (объект точки кастомизации) |
|
(C++20) | задаёт диапазон, который знает свой размер за константное время (концепция) |
|
(C++20) | возвращает расстояние между итератором и sentinels, или между началом и концом диапазона (niebloid) |
|
(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