std::span::span(3)

πŸ“¦ version 2024.07.05, in nixpkgs unstable, opensuse-leap 16.0

welcome to std::span::span(3) from the C++ Standard Libary β€” yes bestie, that's the manual name, and the title is literally std::span::span πŸ’…βœ¨.

🌸 NAME 🌸

std::span::span β€” std::span::span (that's the whole name section, and honestly? iconic.)

✨ Synopsis ✨

the overload lineup, no cap:

constexpr span() noexcept;                                        (1)
(since C++20)

template< class It >
explicit(extent != std::dynamic_extent)
constexpr span( It first, size_type count );                      (2)
(since C++20)

template< class It, class End >
explicit(extent != std::dynamic_extent)
constexpr span( It first, End last );                             (3)
(since C++20)

template< std::size_t N >
constexpr span( std::type_identity_t<element_type> (&arr)[N] ) noexcept;    (4)
(since C++20)

template< class U, std::size_t N >                                (5)
(since C++20)
constexpr span( std::array<U, N>& arr ) noexcept;

template< class U, std::size_t N >                                (6)
(since C++20)
constexpr span( const std::array<U, N>& arr ) noexcept;

template< class R >
explicit(extent != std::dynamic_extent)
constexpr span( R&& range );                                      (7)
(since C++20)

explicit(extent != std::dynamic_extent)
constexpr span( std::initializer_list<value_type> il ) noexcept;  (8)
(since C++26)

template< class U, std::size_t N >
explicit(extent != std::dynamic_extent && N == std::dynamic_extent)
constexpr span( const std::span<U, N>& source ) noexcept;         (9)
(since C++20)

constexpr span( const span& other ) noexcept = default;
(10) (since C++20)

constructs a span. like, that's the whole gig 🫢.

🫢 overload-by-overload tea 🫢

  1. (1) β€” constructs an empty span where data() == nullptr and size() == 0. she participates in overload resolution only if extent == 0 || extent == std::dynamic_extent.
  2. (2) β€” constructs a span that is a view over the range [first, first + count); the resulting span has data() == std::to_address(first) and size() == count.
    • > 🚨 UB alert: the behavior is undefined if [first, first + count) is not a valid range, if It does not actually model contiguous_iterator, or if extent != std::dynamic_extent && count != extent.
    • this overload participates in overload resolution only if:
      • It satisfies contiguous_iterator,
      • the conversion from std::iter_reference_t<It> to element_type is at most a qualification conversion.
  3. (3) β€” constructs a span that is a view over the range [first, last); the resulting span has data() == std::to_address(first) and size() == last-first.
    • > 🚨 UB alert: the behavior is undefined if [first, last) is not a valid range, if It does not actually model contiguous_iterator, if End does not actually model sized_sentinel_for for It, or if extent != std::dynamic_extent && last-first != extent.
    • this overload participates in overload resolution only if:
      • It satisfies contiguous_iterator,
      • End satisfies sized_sentinel_for for It,
      • the conversion from std::iter_reference_t<It> to element_type is at most a qualification conversion, and
      • std::is_convertible_v<End, std::size_t> is false.
  4. 4-6) β€” constructs a span that is a view over the array arr; the resulting span has size() == N and data() == std::data(arr).
    • these overloads participate in overload resolution only if extent == std::dynamic_extent || N == extent is true and the conversion from std::remove_pointer_t<decltype(data(arr))> to element_type is at most a qualification conversion.
  5. (7) β€” constructs a span that is a view over the range range; the resulting span has size() == std::ranges::size(range) and data() == std::ranges::data(range).
    • > 🚨 UB alert: the behavior is undefined if R does not actually model contiguous_range and sized_range, or if R does not model borrowed_range while element_type is non-const, or both extent != dynamic_extent and std::ranges::size(range) != extent are true.
    • this overload participates in overload resolution only if:
      • R satisfies contiguous_range and sized_range,
      • either R satisfies borrowed_range or std::is_const_v<element_type> is true,
      • std::remove_cvref_t<R> is not a specialization of std::span,
      • std::remove_cvref_t<R> is not a specialization of std::array,
      • std::is_array_v<std::remove_cvref_t<R>> is false, and
      • the conversion from std::ranges::range_reference_t<R> to element_type is at most a qualification conversion.
  6. (8) β€” constructs a span that is a view over the initializer list il; the resulting span has size() == il.size() and data() == il.begin().
    • > 🚨 UB alert: the behavior is undefined if both extent != dynamic_extent and il.size() != extent are true.
    • this overload participates in overload resolution only if std::is_const_v<element_type> is true.
  7. (9) β€” converting constructor from another span source; the resulting span has size() == source.size() and data() == source.data().
    • > 🚨 UB alert: the behavior is undefined if both extent != dynamic_extent and source.size() != extent are true.
    • this overload participates in overload resolution only if at least one of extent == std::dynamic_extent, N == std::dynamic_extent and N == extent is true and the conversion from U to element_type is at most a qualification conversion.
  8. (10) β€” defaulted copy constructor copies the size and data pointer; the resulting span has size() == other.size() and data() == other.data().

πŸ’… Parameters πŸ’…

  • first β€” iterator to the first element of the sequence
  • count β€” number of elements in the sequence
  • last β€” iterator past the last element of the sequence or another sentinel
  • arr β€” array to construct a view for
  • range β€” range to construct a view for
  • source β€” another span to convert from
  • other β€” another span to copy from

πŸ’€ Exceptions πŸ’€

  • 2) throws nothing.
  • 3) throws what and when last - first throws.
  • 7) throws what and when std::ranges::size(r) and std::ranges::data(r) throw.

🧚 Notes 🧚

feature-test macro check, bestie:

  • __cpp_lib_span_initializer_list β€” value 202311L β€” (C++26) β€” feature: Constructing std::span from a std::initializer_list, (8).

🌈 Example 🌈

// Run this code

#include <array>
#include <iostream>
#include <span>
#include <vector>

void print_span(std::span<const int> s)
{
    for (int n : s)
        std::cout << n << ' ';
    std::cout << '\n';
}

int main()
{
    int c[]{1, 2, 3};
    print_span(c); // constructs from array

    std::array a{4, 5, 6};
    print_span(a); // constructs from std::array

    std::vector v{7, 8, 9};
    print_span(v); // constructs from std::vector

#if __cpp_lib_span_initializer_list
    print_span({0, 1, 2}); // constructs from initializer_list
#else
    print_span({{0, 1, 2}}); // ditto, a workaround
#endif
}

πŸ“ Output πŸ“

1 2 3
4 5 6
7 8 9
0 1 2

πŸ‘€ See also πŸ‘€

  • data β€” direct access to the underlying contiguous storage β€” (public member function)
  • size β€” returns the number of elements β€” (public member function)
  • operator= β€” assigns a span β€” (public member function)
  • size, ssize β€” returns the size of a container or array β€” (C++17), (C++20) β€” (function template)
  • data β€” obtains the pointer to the underlying array β€” (C++17) β€” (function template)

okay that's the page! cute sign-off time: source/version/date is http://cppreference.com, 2024.06.10, and it's all for std::span::span(3) β€” mwah πŸ’–πŸŽ€πŸ¦‹

πŸ“¦ where this page comes from