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

目录

[编辑] 参数

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

[编辑] 效果

 重载   构造后的 data()   构造后的 size() 
(1) nullptr 0
(2) std::to_address(first) count
(3) last - first
(4) std::data(arr) N
(5)
(6)
(7) ranges::data(r) ranges::size(r)
(8) il.begin() il.size()
(9) source.data() source.size()
(10) other.data() other.size()

[编辑] 约束和补充信息

[编辑] 大小限制

如果 extent 不是 std::dynamic_extent,并且源范围的大小与 extent 不同,那么无法构造 span 对象。

这些重载只有在以下表达式的结果是 true 时才会参与重载决议:

1) extent == std::dynamic_extent || extent == 0
4-6) extent == std::dynamic_extent || extent == N
9) extent == std::dynamic_extent || N == std::dynamic_extent || extent == N


如果以下表达式的结果是 false,那么行为未定义。

(C++26 前)

如果以下表达式的结果是 false,那么:

  • 如果实现是硬化实现,那么就会发生契约违背。并且契约违背处理函数在“观察”求值语义下返回时行为未定义。
  • 如果实现不是硬化实现,那么行为未定义。
(C++26 起)
2) extent == std::dynamic_extent || extent == count
3) extent == std::dynamic_extent || extent == last - first
7) extent == std::dynamic_extent || extent == ranges::size(r)
8) extent == std::dynamic_extent || extent == il.size()
9) extent == std::dynamic_extent || extent == source.size()

[编辑] 转换要求

如果 element_type 与源范围的元素类型不同,并且后者不能通过限定性转换转换到前者,那么无法构造 span 对象。

这些重载只有在std::is_convertible_v<U(*)[], element_type(*)[]>true时才会参与重载决议,其中 U 定义如下:

4-6) std::remove_pointer_t<decltype(std::data(arr))>
9) U

[编辑] 概念要求

如果某些模板实参没有实现指定的概念,那么无法构造 span 对象。

这些重载只有在指定的模板形参对应的模板实参满足对应的概念时才会参与重载决议。如果它不满足任何对应的概念的语义要求,那么行为未定义:

 重载  模板形参  概念 备注
(2) It contiguous_iterator
(3) It contiguous_iterator
End  sized_sentinel_for<It> 
(7) R contiguous_range
sized_range
borrowed_range 只有在 std::is_const_v<element_type>false 时需要实现

[编辑] 其他约束

2) 如果 [firstfirst + count) 不是有效范围,那么行为未定义。
3) 此重载只有在std::is_convertible_v<End, std::size_t>false时才会参与重载决议。
如果[firstlast) 不是有效范围,那么行为未定义。
7) 此重载只有在满足以下所有条件时才会参与重载决议:
8) 此重载只有在std::is_const_v<element_type>true时才会参与重载决议。

[编辑] 异常

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)
获得指向底层数组的指针
(函数模板) [编辑]