Namespaces
Variants

std::size, std::ssize

Из ru.cppreference.net
 
 
Библиотека итераторов
Концепты итераторов
Примитивы итераторов
Концепты и утилиты алгоритмов
Концепты косвенной вызываемости
Общие требования к алгоритмам
(C++20)
(C++20)
(C++20)
Утилиты
(C++20)
Адаптеры итераторов
Доступ к диапазонам
(C++11)(C++14)
(C++14)(C++14)  
(C++11)(C++14)
(C++14)(C++14)  
(C++17)(C++20)
(C++17)
(C++17)
 
Определён в заголовке <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)

Возвращает размер заданного диапазона.

1,2) Возвращает c.size(), преобразованный в тип возвращаемого значения при необходимости.
3,4) Возвращает N.

Параметры

c - контейнер или представление с функцией-членом size
array - массив произвольного типа

Возвращаемое значение

1) c. size ( )
2) static_cast < std:: common_type_t < std:: ptrdiff_t ,
std:: make_signed_t < decltype ( c. size ( ) ) >>> ( c. size ( ) )
3,4) N

Исключения

1,2) Может выбрасывать исключения, определяемые реализацией.

Перегрузки

Для классов и перечислений, которые не предоставляют подходящую функцию-член size() , но могут быть обнаружены, могут быть предоставлены пользовательские перегрузки size .

Перегрузки size , найденные с помощью поиска, зависимого от аргументов , могут использоваться для настройки поведения std :: ranges:: size , std :: ranges:: ssize и std :: ranges:: empty .

(начиная с 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;
}
Все HTML-теги, атрибуты и код внутри `
` тегов сохранены без изменений. Текст вне тегов ``, `
`, `` переведен на русский язык с сохранением профессионального стиля.

Примечания

Макрос тестирования возможностей Значение Стандарт Функция
__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)
возвращает целое число, равное размеру диапазона
(объект точки настройки)
возвращает знаковое целое число, равное размеру диапазона
(объект точки настройки)