deduction guides for std::span

From cppreference.com
< cpp‎ | container‎ | span
 
 
 
std::span
Member functions
(C++20)
Element access
(C++20)
(C++20)
Iterators
(C++20)(C++23)
(C++20)(C++23)
Observers
(C++20)
Subviews
(C++20)
Non-member functions
Non-member constant
Deduction guides(C++20)
 
Defined in header <span>
template< class It, class EndOrSize >
span( It, EndOrSize ) -> span<std::remove_reference_t<std::iter_reference_t<It>>>;
(1) (since C++20)
template< class T, std::size_t N >
span( T (&)[N] ) -> span<T, N>;
(2) (since C++20)
template< class T, std::size_t N >
span( std::array<T, N>& ) -> span<T, N>;
(3) (since C++20)
template< class T, std::size_t N >
span( const std::array<T, N>& ) -> span<const T, N>;
(4) (since C++20)
template< class R >
span( R&& ) -> span<std::remove_reference_t<std::ranges::range_reference_t<R>>>;
(5) (since C++20)

The following deduction guides are provided for span.

1) Allows the element type to be deduced from the iterator-sentinel pair. This overload participates in overload resolution only if It satisfies contiguous_iterator
2-4) Allows the static extent to be deduced from built-in arrays and std::array.
5) Allows the element type to be deduced from ranges. This overload participates in overload resolution only if R satisfies contiguous_range

Example

#include <array>
#include <cstddef>
#include <iomanip>
#include <iostream>
#include <span>
#include <string_view>
#include <vector>
 
void print(std::string_view rem = "", std::size_t size_of = 0, std::size_t extent = 0)
{
    if (rem.empty())
    {
        std::cout << "name │ sizeof │ extent\n─────┼────────┼────────\n";
        return;
    }
    std::cout << std::setw(4) << rem << " │ " << std::setw(6) << size_of << " │ ";
    if (extent == std::dynamic_extent)
        std::cout << "dynamic";
    else
        std::cout << extent;
    std::cout << '\n';
}
 
int main()
{
    int a[] {1, 2, 3, 4, 5};
 
    print();
    std::span s1 {std::begin(a), std::end(a)}; // guide (1)
    print("s1", sizeof s1, s1.extent);
 
    std::span s2 {std::begin(a), 3}; // guide (1)
    print("s2", sizeof s2, s2.extent);
 
    std::span s3 {a}; // guide (2)
    print("s3", sizeof s3, s3.extent);
 
    std::span<int> s4 {a}; // does not use a guide, makes a dynamic span
    print("s4", sizeof s4, s4.extent);
 
    std::array arr {6, 7, 8};
    std::span s5 {arr}; // guide (3)
    print("s5", sizeof s5, s5.extent);
    s5[0] = 42; // OK, element_type is 'int'
 
    const std::array arr2 {9, 10, 11};
    std::span s6 {arr2}; // guide (4)
    print("s6", sizeof s6, s6.extent);
    // s6[0] = 42; // Error: element_type is 'const int'
 
    std::vector v {66, 69, 99};
    std::span s7 {v}; // guide (5)
    print("s7", sizeof s7, s7.extent);
}

Output:

name │ sizeof │ extent
─────┼────────┼────────
  s1 │     16 │ dynamic
  s2 │     16 │ dynamic
  s3 │      8 │ 5
  s4 │     16 │ dynamic
  s5 │      8 │ 3
  s6 │      8 │ 3
  s7 │     16 │ dynamic