std::ranges::ssize
Определено в заголовке <ranges> | ||
|---|---|---|
Определено в заголовке <iterator> | ||
inline namespace /*unspecified*/ {
inline constexpr /*unspecified*/ ssize = /*unspecified*/;
}
| (с C++20) (объект точки кастомизации) | |
| Подпись вызова | ||
template< class T >
requires /* see below */
constexpr /*signed-integer-like*/ ssize( T&& t );
| (с C++20) |
Возвращает размер диапазона, преобразованного к знакомому типу.
Если ranges::size(t) корректно сформирован, вызов ranges::ssize эквивалентен static_cast<MadeSigned>(ranges::size(t)), где MadeSigned обозначает
- соответствующую знакопеременную версию
decltype(ranges::size(t)), если она ширеstd::ptrdiff_t, или -
std::ptrdiff_tв противном случае.
Если ranges::size(t) некорректен, вызов ranges::ssize также некорректен, что может привести к неудаче подстановки, когда ranges::ssize(t) появляется в непосредственном контексте шаблона.
Объекты точки кастомизации
Имя ranges::ssize обозначает объект точки кастомизации, который представляет собой const функциональный объект типа литерального semiregular класса. Для целей пояснения, неквалифицированная версия его типа обозначается как __ssize_fn.
Все экземпляры __ssize_fn равны. Эффекты вызова разных экземпляров типа __ssize_fn с одними и теми же аргументами эквивалентны, независимо от того, является ли выражение, обозначающее экземпляр, lvalue или rvalue, и квалифицируется ли оно как const (однако, не требуется, чтобы экземпляр с квалификацией volatile можно было вызывать). Таким образом, ranges::ssize может быть свободно скопирован, и его копии могут использоваться взаимозаменяемо.
Учитывая набор типов Args..., если std::declval<Args>()... удовлетворяют требованиям к аргументам для ranges::ssize выше, __ssize_fn моделирует
-
std::invocable<__ssize_fn, Args...>, -
std::invocable<const __ssize_fn, Args...>, -
std::invocable<__ssize_fn&, Args...>, и -
std::invocable<const __ssize_fn&, Args...>.
В противном случае ни один оператор вызова функции __ssize_fn не участвует в разрешении перегрузки.
Примечания
Если ranges::ssize(e) допустимо для выражения e, тип возвращаемого значения — это знаковый целочисленный тип, то есть целочисленный тип, для которого std::is_signed_v является true, или знаковый целочисленный тип.
Ширина целочисленных типов может быть определена с помощью std::numeric_limits::digits.
Пример
#include <array>
#include <iostream>
#include <ranges>
#include <type_traits>
int main()
{
std::array arr{1, 2, 3, 4, 5};
auto s = std::ranges::ssize(arr);
std::cout << "ranges::ssize(arr) = " << s << '\n'
<< "ranges::ssize is "
<< (std::is_signed_v<decltype(s)> ? "signed" : "unsigned")
<< '\n';
std::cout << "reversed arr: ";
for (--s; s >= 0; --s)
std::cout << arr[s] << ' ';
std::cout << "\n" "s = " << s << '\n';
}Вывод:
ranges::ssize(arr) = 5 ranges::ssize is signed reversed arr: 5 4 3 2 1 s = -1
Отчеты об ошибках
Следующие отчеты об ошибках, изменяющие поведение, были применены ретроактивно к ранее опубликованным стандартам C++.
| DR | Применено к | Поведение, как опубликовано | Правильное поведение |
|---|---|---|---|
| LWG 3403 | C++20 |
ranges::size работало для некоторых типов, не являющихся диапазонами, но ranges::ssize нет | работает |
См. также
|
(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/ssize