Namespaces
Variants

std::size, std::ssize

From cppreference.net
 
 
Iterator library
Iterator concepts
Iterator primitives
Algorithm concepts and utilities
Indirect callable concepts
Common algorithm requirements
(C++20)
(C++20)
(C++20)
Utilities
(C++20)
Iterator adaptors
Range access
(C++11)(C++14)
(C++14)(C++14)  
(C++11)(C++14)
(C++14)(C++14)  
(C++17)(C++20)
(C++17)
(C++17)
 
Defined in header <array>
Defined in header <deque>
Defined in header <flat_map>
 (since C++23)
Defined in header <flat_set>
 (since C++23)
Defined in header <forward_list>
Defined in header <inplace_vector>
 (since C++26)
Defined in header <iterator>
Defined in header <list>
Defined in header <map>
Defined in header <optional>
 (since C++26)
Defined in header <regex>
Defined in header <set>
Defined in header <span>
 (since C++20)
Defined in header <stacktrace>
 (since C++23)
Defined in header <string>
Defined in header <string_view>
Defined in header <unordered_map>
Defined in header <unordered_set>
Defined in header <valarray>
Defined in header <vector>
template< class C >
constexpr auto size( const C& c ) noexcept(noexcept(c.size()))
    -> decltype(c.size());
(1) (since 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) (since C++20)
template< class T, std::size_t N >
constexpr std::size_t size( const T (&array)[N] ) noexcept;
(3) (since C++17)
template< class T, std::ptrdiff_t N >
constexpr std::ptrdiff_t ssize( const T (&array)[N] ) noexcept;
(4) (since C++20)

Returns the size of the given range.

1,2) Returns c.size(), converted to the return type if necessary.
3,4) Returns N.

Parameters

c - a container or view with a size member function
array - an array of arbitrary type

Return value

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

Exceptions

1,2) What and when the underlying c.size() call throws.

Overloads

Custom overloads of size may be provided for classes and enumerations that do not expose a suitable size() member function, yet can be detected.

Overloads of size found by argument-dependent lookup can be used to customize the behavior of std::ranges::size, std::ranges::ssize, and std::ranges::empty.

(since C++20)

Possible implementation

size (1)
template<class C>
constexpr auto size(const C& c) noexcept(noexcept(c.size()))
    -> decltype(c.size())
{
    return c.size();
}
ssize (2)
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())>>
{
    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;
}

Notes

Feature-test macro Value Std Feature
__cpp_lib_nonmember_container_access 201411L (C++17) std::size(), std::data and std::empty
__cpp_lib_ssize 201902L (C++20) std::ssize() (2,4) and unsigned std::span::size()

Example

#include <cassert>
#include <cstring>
#include <iostream>
#include <vector>

int main()
{
    // Works with containers
    std::vector<int> v{3, 1, 4};
    assert(std::size(v) == 3);
    
    // And works with built-in arrays too
    int a[]{-5, 10, 15};
    // Returns the number of elements (not bytes) as opposed to sizeof
    assert(std::size(a) == 3);
    std::cout << "size of a[]: " << sizeof a << '\n'; // 12, if sizeof(int) == 4
    
    // Provides a safe way (compared to sizeof) of getting string buffer size
    const char str[] = "12345";
    // These are fine and give the correct result
    assert(std::size(str) == 6);
    assert(sizeof(str) == 6);
    
    // But use of sizeof here is a common source of bugs
    const char* str_decayed = "12345";
    // std::cout << std::size(str_decayed) << '\n'; // Usefully fails to compile
    std::cout << sizeof(str_decayed) << '\n'; // Prints the size of the pointer!
    
    // Since C++20 the signed size (std::ssize) is available
    auto i = std::ssize(v);
    for (--i; i != -1; --i)
        std::cout << v[i] << (i ? ' ' : '\n');
    assert(i == -1);

    // Note that the string literal includes the ending null character, which
    // will be part of the constructed characters array. This makes std::size
    // behave differently from std::strlen and 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);
}

Possible output:

size of a[]: 12
8
4 1 3

Defect report

The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

DR Applied to Behavior as published Correct behavior
P3016R6 C++17
C++20
1) std::size was not required to propagate exception specification
2) std::ssize was not required to propagate exception specification
required

See also

signed integer type returned when subtracting two pointers
(typedef)
unsigned integer type returned by the sizeof operator
(typedef)
returns an integer equal to the size of a range
(customization point object)
returns a signed integer equal to the size of a range
(customization point object)