std::size, std::ssize
| Определён в заголовке <array>
|
||
| Определён в заголовке <deque>
|
||
| Определён в заголовке <flat_map>
|
(начиная с C++23) |
|
| Определён в заголовке <flat_set>
|
(начиная с C++23) |
|
| Определён в заголовке <forward_list>
|
||
| Определён в заголовке <inplace_vector>
|
(начиная с C++26) |
|
| Определён в заголовке <iterator>
|
||
| Определён в заголовке <list>
|
||
| Определён в заголовке <map>
|
||
| Определён в заголовке <optional>
|
(начиная с C++26) |
|
| Определён в заголовке <regex>
|
||
| Определён в заголовке <set>
|
||
| Определён в заголовке <span>
|
(начиная с C++20) |
|
| Определён в заголовке <stacktrace>
|
(начиная с C++23) |
|
| Определён в заголовке <string>
|
||
| Определён в заголовке <string_view>
|
||
| Определён в заголовке <unordered_map>
|
||
| Определён в заголовке <unordered_set>
|
||
| Определён в заголовке <valarray>
|
||
| Определён в заголовке <vector>
|
||
template< class C >
constexpr auto size( const C& c ) noexcept(noexcept(c.size()))
-> decltype(c.size());
|
(1) | (начиная с C++17) |
template< class C >
constexpr auto ssize( const C& c ) noexcept(noexcept(c.size()))
-> std::common_type_t<std::ptrdiff_t,
std::make_signed_t<decltype(c.size())>>;
|
(2) | (начиная с C++20) |
template< class T, std::size_t N >
constexpr std::size_t size( const T (&array)[N] ) noexcept;
|
(3) | (начиная с C++17) |
template< class T, std::ptrdiff_t N >
constexpr std::ptrdiff_t ssize( const T (&array)[N] ) noexcept;
|
(4) | (начиная с C++20) |
Возвращает размер заданного диапазона.
c.size(), преобразованный в тип возвращаемого значения при необходимости.N.Параметры
| c | - |
контейнер или представление с функцией-членом
size
|
| array | - | массив произвольного типа |
Возвращаемое значение
std:: make_signed_t < decltype ( c. size ( ) ) >>> ( c. size ( ) )
Исключения
Перегрузки
Для классов и перечислений, которые не предоставляют подходящую функцию-член
size()
, но могут быть обнаружены, могут быть предоставлены пользовательские перегрузки
size
.
|
Перегрузки
|
(начиная с C++20) |
Возможная реализация
| size (1) |
|---|
template<class C> constexpr auto size(const C& c) -> decltype(c.size()) { return c.size(); } |
| ssize (2) |
template<class C> constexpr auto ssize(const C& c) -> std::common_type_t<std::ptrdiff_t, std::make_signed_t<decltype(c.size())>> { using R = std::common_type_t<std::ptrdiff_t, std::make_signed_t<decltype(c.size())>>; return static_cast<R>(c.size()); } |
| size (3) |
template<class T, std::size_t N> constexpr std::size_t size(const T (&array)[N]) noexcept { return N; } |
| ssize (4) |
template<class T, std::ptrdiff_t N> constexpr std::ptrdiff_t ssize(const T (&array)[N]) noexcept { return N; } |
` тегов сохранены без изменений. Текст вне тегов ``, ``, `
Примечания
| Макрос тестирования возможностей | Значение | Стандарт | Функция |
|---|---|---|---|
__cpp_lib_nonmember_container_access
|
201411L
|
(C++17) |
std::size()
,
std::data
и
std::empty
|
__cpp_lib_ssize
|
201902L
|
(C++20) |
std::ssize()
(
2,4
)
и беззнаковый
std::span::size()
|
Пример
#include <cassert> #include <cstring> #include <iostream> #include <vector> int main() { // Работает с контейнерами std::vector<int> v{3, 1, 4}; assert(std::size(v) == 3); // А также работает со встроенными массивами int a[]{-5, 10, 15}; // Возвращает количество элементов (не байт) в отличие от sizeof assert(std::size(a) == 3); std::cout << "size of a[]: " << sizeof a << '\n'; // 12, если sizeof(int) == 4 // Предоставляет безопасный способ (по сравнению с sizeof) получения размера строкового буфера const char str[] = "12345"; // Эти варианты работают корректно и дают правильный результат assert(std::size(str) == 6); assert(sizeof(str) == 6); // Но использование sizeof здесь является распространенным источником ошибок const char* str_decayed = "12345"; // std::cout << std::size(str_decayed) << '\n'; // Полезно не компилируется std::cout << sizeof(str_decayed) << '\n'; // Выводит размер указателя! // Начиная с C++20 доступен знаковый размер (std::ssize) auto i = std::ssize(v); for (--i; i != -1; --i) std::cout << v[i] << (i ? ' ' : '\n'); assert(i == -1); // Обратите внимание, что строковый литерал включает завершающий нулевой символ, // который будет частью созданного массива символов. Это приводит к тому, что std::size // ведет себя иначе, чем std::strlen и std::string::size: constexpr char symbols[] = "0123456789"; static_assert(std::size(symbols) == 11); static_assert(std::string(symbols).size() == 10); assert(std::strlen(symbols) == 10); }
Возможный вывод:
size of a[]: 12 8 4 1 3
Отчёт о дефектах
Следующие отчёты о дефектах, изменяющих поведение, были применены ретроактивно к ранее опубликованным стандартам C++.
| DR | Применено к | Поведение, как опубликовано | Корректное поведение |
|---|---|---|---|
| P3016R6 | C++17 C++20 |
1) std::size не требовалось распространять спецификацию исключений2) std::ssize не требовалось распространять спецификацию исключений
|
требуется |
Смотрите также
|
знаковый целочисленный тип, возвращаемый при вычитании двух указателей
(typedef) |
|
|
беззнаковый целочисленный тип, возвращаемый оператором
sizeof
(typedef) |
|
|
(C++20)
|
возвращает целое число, равное размеру диапазона
(объект точки настройки) |
|
(C++20)
|
возвращает знаковое целое число, равное размеру диапазона
(объект точки настройки) |