std::span<T,Extent>::span

来自cppreference.com
< cpp‎ | container‎ | span
constexpr span() noexcept;
(1) (C++20 起)
template< class It >

explicit(extent != std::dynamic_extent)

constexpr span( It first, size_type count );
(2) (C++20 起)
template< class It, class End >

explicit(extent != std::dynamic_extent)

constexpr span( It first, End last );
(3) (C++20 起)
template< std::size_t N >
constexpr span( std::type_identity_t<element_type> (&arr)[N] ) noexcept;
(4) (C++20 起)
template< class U, std::size_t N >
constexpr span( std::array<U, N>& arr ) noexcept;
(5) (C++20 起)
template< class U, std::size_t N >
constexpr span( const std::array<U, N>& arr ) noexcept;
(6) (C++20 起)
template< class R >

explicit(extent != std::dynamic_extent)

constexpr span( R&& range );
(7) (C++20 起)
explicit(extent != std::dynamic_extent)
constexpr span( std::initializer_list<value_type> il ) noexcept;
(8) (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) (C++20 起)
constexpr span( const span& other ) noexcept = default;
(10) (C++20 起)

构造 span

1) 构造空 span 使其 data() == nullptrsize() == 0
2) 构造作为范围 [firstfirst + count) 上的视图的 span;产生的 span 有 data() == std::to_address(first)size() == count
  • [firstfirst + count) 不是合法范围,若 It 不实际实现 contiguous_iterator,或若 extent != std::dynamic_extent && count != extent,则行为未定义。
  • 此重载只有在
时才会参与重载决议。
3) 构造作为范围 [firstlast) 上的视图的 span;产生的 span 有 data() == std::to_address(first)size() == last-first
时才会参与重载决议。
4-6) 构造作为数组 arr 上的视图的 span;产生的 span 有 size() == Ndata() == std::data(arr)
7) 构造作为范围 range 上的视图的 span;产生的 span 有 size() == std::ranges::size(r)data() == std::ranges::data(range)
时才会参与重载决议。
8) 构造作为初始化式列表 il 上的视图的 span;产生的 span 有 size() == il.size()data() == il.begin()
  • extent != dynamic_extentil.size() != extent 均为 true,则行为未定义。
  • 仅当 std::is_const_v<element_type>true 时,此重载参与重载决议。
9) 从另一 span source 的转换构造函数;产生的 span 有 size() == source.size()data() == source.data()
  • extent != dynamic_extentsource.size() != extent 均为 true,则行为未定义。
  • 此重载只有在extent == std::dynamic_extentN == std::dynamic_extentN == extent 至少一者为 true,且从 Uelement_type 的转换至多为限定转换时才会参与重载决议。
10) 预置的赋值构造函数复制大小与数据指针;产生的 span 有 size() == other.size()data() == other.data()

参数

first - 指向序列首元素的迭代器
count - 序列的元素数
last - 指向序列末元素后一位置的迭代器或另一哨位
arr - 用于构造视图的数组
range - 用于构造视图的范围
source - 要转换的另一 span
other - 要复制的另一 span

异常

2) 不抛出。
3)last - first 抛出时抛出其所抛出的异常。
7)std::ranges::size(r)std::ranges::data(r) 抛出时抛出其所抛出的异常。

注解

功能特性测试 标准 功能特性
__cpp_lib_span_initializer_list 202311L (C++26) 以一个 std::initializer_list 构造std::span(8)

示例

#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); // 从数组构造
 
    std::array a{4, 5, 6};
    print_span(a); // 从 std::array 构造
 
    std::vector v{7, 8, 9};
    print_span(v); // 从 std::vector 构造
 
#if __cpp_lib_span_initializer_list
    print_span({0, 1, 2}); // 从 initializer_list 构造
#else
    print_span({{0, 1, 2}}); // 同上,一种变通方法
#endif
}

输出:

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

参阅

直接访问底层连续存储
(公开成员函数)
返回元素数
(公开成员函数)
赋值 span
(公开成员函数)
(C++17)(C++20)
返回容器或数组的大小
(函数模板)
(C++17)
获得指向底层数组的指针
(函数模板)