std::span

来自cppreference.com
< cpp‎ | container
在标头 <span> 定义
template<

    class T,
    std::size_t Extent =std::dynamic_extent

>class span;
(C++20 起)

类模板 span 所描述的对象可以指代对象的连续序列,序列的首元素处于位置零。span 能拥有静态 长度,此时序列中的元素数在编译期已知并在类型中编码,也可以拥有动态 长度。

对于 spans,当有操作使得范围 [s.data()s.data()+ s.size()) 中的指针失效时,到 s 的元素的指针、迭代器和引用也会失效。

std::span 的每个特化都可平凡复制(TriviallyCopyable)

(C++23 起)

目录

[编辑]模板形参

T - 元素类型;必须是完整对象类型且非抽象类
Extent - 序列中的元素数,span 拥有动态长度时是 std::dynamic_extent

[编辑]嵌套类型

类型 定义
element_typeT
value_typestd::remove_cv_t<T>
size_typestd::size_t
difference_typestd::ptrdiff_t
pointerT*
const_pointerconst T*
referenceT&
const_referenceconst T&
iterator[1] 由实现定义的老式随机访问迭代器(LegacyRandomAccessIterator) 常量表达式迭代器(ConstexprIterator) 老式连续迭代器(LegacyContiguousIterator) ,它的 value_typevalue_type
const_iterator(C++23 起)std::const_iterator<iterator>
reverse_iteratorstd::reverse_iterator<iterator>
const_reverse_iterator(C++23 起)std::reverse_iterator<const_iterator>
  1. 如果 T 没有 const 限定,那么 iterator 是可变迭代器。

容器(Container) 的迭代器类型上的所有要求同样适用于 spaniterator 类型。

[编辑]数据成员

成员 描述
constexprstd::size_t extent
[静态]
Extent
(公开静态成员常量)
pointerdata_ 指向底层序列的指针
(仅用于阐述的成员对象*)
size_typesize_
(仅当为动态 长度时提供)
元素个数
(仅用于阐述的成员对象*)

[编辑]成员函数

构造 span
(公开成员函数)[编辑]
赋值 span
(公开成员函数)[编辑]
(析构函数)
(隐式声明)
析构 span
(公开成员函数)
迭代器
返回指向起始的迭代器
(公开成员函数)[编辑]
(C++23)
返回指向末尾的迭代器
(公开成员函数)[编辑]
返回指向起始的逆向迭代器
(公开成员函数)[编辑]
(C++23)
返回指向末尾的逆向迭代器
(公开成员函数)[编辑]
元素访问
访问第一个元素
(公开成员函数)[编辑]
访问最后一个元素
(公开成员函数)[编辑]
(C++26)
带越界检查访问指定的元素
(公开成员函数)[编辑]
访问指定的元素
(公开成员函数)[编辑]
直接访问底层连续存储
(公开成员函数)[编辑]
观察器
返回元素数
(公开成员函数)[编辑]
返回以字节计的序列大小
(公开成员函数)[编辑]
检查序列是否为空
(公开成员函数)[编辑]
子视图
获得由序列前 N 个元素组成的子段
(公开成员函数)[编辑]
获得由序列末 N 个元素组成的子段
(公开成员函数)[编辑]
获得子段
(公开成员函数)[编辑]

[编辑]非成员函数

转换 span 为对其底层字节的视图
(函数模板)[编辑]

[编辑]辅助常量

std::size_t 类型的常量,指明 span 拥有动态长度
(常量)[编辑]

[编辑]辅助模板

template<class T, std::size_t Extent >
constexprboolranges::enable_borrowed_range<std::span<T, Extent>>=true;
(C++20 起)

ranges::enable_borrowed_range 的此特化使得 span 满足 borrowed_range

template<class T, std::size_t Extent >
constexprboolranges::enable_view<std::span<T, Extent>>=true;
(C++20 起)

ranges::enable_view 的此特化使零或动态长度的 span 满足 view

[编辑]推导指引

[编辑]注解

即使在 C++23 引入正式要求前,所有既存实现中 std::span 的特化都已经是可平凡复制类型。

功能特性测试标准功能特性
__cpp_lib_span202002L(C++20)std::span
__cpp_lib_span_at202311L(C++26)std::span::at
__cpp_lib_span_initializer_list202311L(C++26)以一个 std::initializer_list 构造 std::span

[编辑]示例

示例用 std::span 实现连续范围上的算法。

#include <algorithm>#include <cstddef>#include <iostream>#include <span>   template<class T, std::size_t N>[[nodiscard]]constexprauto slide(std::span<T, N> s, std::size_t offset, std::size_t width){return s.subspan(offset, offset + width <= s.size()? width : 0U);}   template<class T, std::size_t N, std::size_t M>constexprbool starts_with(std::span<T, N> data, std::span<T, M> prefix){return data.size()>= prefix.size()&&std::equal(prefix.begin(), prefix.end(), data.begin());}   template<class T, std::size_t N, std::size_t M>constexprbool ends_with(std::span<T, N> data, std::span<T, M> suffix){return data.size()>= suffix.size()&&std::equal(data.end()- suffix.size(), data.end(), suffix.end()- suffix.size());}   template<class T, std::size_t N, std::size_t M>constexprbool contains(std::span<T, N> span, std::span<T, M> sub){return std::ranges::search(span, sub).begin()!= span.end();}   void println(constauto& seq){for(constauto& elem : seq)std::cout<< elem <<' ';std::cout<<'\n';}   int main(){constexprint a[]{0, 1, 2, 3, 4, 5, 6, 7, 8};constexprint b[]{8, 7, 6};constexprstaticstd::size_t width{6};   for(std::size_t offset{};;++offset)if(auto s = slide(std::span{a}, offset, width);!s.empty()) println(s);elsebreak;   static_assert(""&& starts_with(std::span{a}, std::span{a, 4})&& starts_with(std::span{a +1, 4}, std::span{a +1, 3})&&!starts_with(std::span{a}, std::span{b})&&!starts_with(std::span{a, 8}, std::span{a +1, 3})&& ends_with(std::span{a}, std::span{a +6, 3})&&!ends_with(std::span{a}, std::span{a +6, 2})&& contains(std::span{a}, std::span{a +1, 4})&&!contains(std::span{a, 8}, std::span{a, 9}));}

输出:

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

[编辑]缺陷报告

下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。

缺陷报告 应用于 出版时的行为 正确行为
LWG 3203 C++20 不明确到 span 的元素的指针、迭代器和引用在什么时候会失效 使之明确
LWG 3903 C++20 span 的析构函数声明不是必要的 移除该声明
P2325R3 C++20 非零静态长度的 span 不是 view 所有 span 都是 view

[编辑]参阅

(C++23)
多维非拥有数组视图
(类模板)[编辑]
将迭代器/哨位对结合为一个 view
(类模板)[编辑]
引用在列表初始化中创建的临时数组
(类模板)[编辑]
只读的字符串视图
(类模板)[编辑]
close