std:: span
|
定义于头文件
<span>
|
||
|
template
<
class
T,
|
(C++20 起) | |
类模板
span
描述了一个对象,该对象可以引用一个连续的对象序列,其中序列的第一个元素位于零位置。
span
可以具有
静态
范围(此时序列中的元素数量在编译时已知并编码在类型中),也可以具有
动态
范围。
对于
span
s
,当操作使范围
[
s.
data
(
)
,
s.
data
(
)
+
s.
size
(
)
)
内的指针失效时,指向
s
元素的指针、迭代器和引用也将失效。
|
|
(C++23 起) |
目录 |
模板参数
| T | - | 元素类型;必须是完整的非抽象类对象类型 |
| Extent | - |
序列中的元素数量,若为动态则为
std::dynamic_extent
|
嵌套类型
| 类型 | 定义 |
element_type
|
T
|
value_type
|
std:: remove_cv_t < T > |
size_type
|
std::size_t |
difference_type
|
std::ptrdiff_t |
pointer
|
T * |
const_pointer
|
const T * |
reference
|
T & |
const_reference
|
const T & |
iterator
[1]
|
实现定义的
LegacyRandomAccessIterator
、
ConstexprIterator
和
contiguous_iterator
,其
value_type
为
value_type
|
const_iterator
(C++23 起)
|
std:: const_iterator < iterator > |
reverse_iterator
|
std:: reverse_iterator < iterator > |
const_reverse_iterator
(C++23 起)
|
std:: const_iterator < reverse_iterator > |
-
↑
iterator是一个可变迭代器,如果T不是 const 限定类型。
所有对
容器
迭代器类型的要求同样适用于
span
的
iterator
类型。
数据成员
| 成员 | 描述 |
|
constexpr
std::
size_t
extent
[静态]
|
Extent
(公开静态成员常量) |
pointer
data_
|
指向底层序列的指针
( 仅用于说明的成员对象* ) |
size_type
size_
(仅在范围为 动态 时存在) |
元素数量
( 仅用于说明的成员对象* ) |
成员函数
构造一个
span
(公开成员函数) |
|
赋值一个
span
(公开成员函数) |
|
|
(destructor)
(implicitly declared)
|
析构一个
span
(公开成员函数) |
迭代器 |
|
|
(C++23)
|
返回指向起始的迭代器
(公开成员函数) |
|
(C++23)
|
返回指向末尾的迭代器
(公开成员函数) |
|
(C++23)
|
返回指向起始的逆向迭代器
(公开成员函数) |
|
(C++23)
|
返回指向末尾的逆向迭代器
(公开成员函数) |
元素访问 |
|
|
访问首元素
(公开成员函数) |
|
|
访问末元素
(公开成员函数) |
|
|
(C++26)
|
带边界检查访问指定元素
(公开成员函数) |
|
访问指定元素
(公开成员函数) |
|
|
直接访问底层连续存储
(公开成员函数) |
|
观察器 |
|
|
返回元素数量
(公开成员函数) |
|
|
返回序列的字节大小
(公开成员函数) |
|
|
检查序列是否为空
(公开成员函数) |
|
子视图 |
|
获取由序列前
N
个元素组成的子跨度
(公开成员函数) |
|
获取由序列后
N
个元素组成的子跨度
(公开成员函数) |
|
|
获取子跨度
(公开成员函数) |
|
非成员函数
|
(C++20)
|
将
span
转换为其底层字节的视图
(函数模板) |
辅助常量
|
(C++20)
|
一个
std::size_t
类型的常量,表示该
span
具有动态范围
(常量) |
辅助模板
|
template
<
class
T,
std::
size_t
Extent
>
constexpr bool ranges:: enable_borrowed_range < std :: span < T, Extent >> = true ; |
(C++20 起) | |
此对
ranges::enable_borrowed_range
的特化使
span
满足
borrowed_range
要求。
|
template
<
class
T,
std::
size_t
Extent
>
constexpr bool ranges:: enable_view < std :: span < T, Extent >> = true ; |
(C++20 起) | |
此
ranges::enable_view
的特化使
span
满足
view
要求。
推导指引
注释
在所有现有实现中,
std::span
的特化版本早已是平凡可复制类型,这一特性甚至早于C++23正式引入该要求之前。
| 功能测试 宏 | 值 | 标准 | 功能特性 |
|---|---|---|---|
__cpp_lib_span
|
202002L
|
(C++20) |
std::span
|
202311L
|
(C++26) | std::span::at | |
__cpp_lib_span_initializer_list
|
202311L
|
(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]] constexpr auto 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> constexpr bool 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> constexpr bool 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> constexpr bool contains(std::span<T, N> span, std::span<T, M> sub) { return std::ranges::search(span, sub).begin() != span.end(); } void println(const auto& seq) { for (const auto& elem : seq) std::cout << elem << ' '; std::cout << '\n'; } int main() { constexpr int a[]{0, 1, 2, 3, 4, 5, 6, 7, 8}; constexpr int b[]{8, 7, 6}; constexpr static std::size_t width{6}; for (std::size_t offset{}; ; ++offset) if (auto s = slide(std::span{a}, offset, width); !s.empty()) println(s); else break; 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</span
缺陷报告
以下行为变更缺陷报告被追溯应用于先前发布的C++标准。
| 缺陷报告 | 应用于 | 发布时的行为 | 正确行为 |
|---|---|---|---|
| LWG 3203 | C++20 |
关于
span
元素的指针、迭代器和引用何时失效的规定不明确
|
已明确说明 |
| LWG 3903 | C++20 |
span
的析构函数声明是多余的
|
已移除该声明 |
| P2325R3 | C++20 |
具有非零静态范围的
span
不被视为
view
|
所有
span
都是
view
|
参见
|
(C++23)
|
多维非拥有数组视图
(类模板) |
|
(C++20)
|
将迭代器-哨位对组合为
view
(类模板) |
|
(C++11)
|
引用在
列表初始化
中创建的临时数组
(类模板) |
|
(C++17)
|
只读字符串视图
(类模板) |