std::span<T,Extent>::span
来自cppreference.com
constexpr span() noexcept; |
(1) | (C++20 起) |
template< class It > explicit(extent != std::dynamic_extent) |
(2) | (C++20 起) |
template< class It, class End > explicit(extent != std::dynamic_extent) |
(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) |
(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) |
(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
定义如下:
2,3) std::remove_reference_t<std::iter_reference_t<It>>
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 时需要实现 |
[编辑] 其他约束
如果
[
first,
last)
不是有效范围,那么行为未定义。7) 此重载只有在满足以下所有条件时才会参与重载决议:
- std::remove_cvref_t<R> 不是
std::span
或 std::array 的特化。 - std::is_array_v<std::remove_cvref_t<R>> 是 false。
[编辑] 异常
2) 不抛出。
3) 在 last - first 抛出时抛出其所抛出的异常。
[编辑] 注解
功能特性测试宏 | 值 | 标准 | 功能特性 |
---|---|---|---|
__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) |
获得指向底层数组的指针 (函数模板) |