std::span 的推导指引
来自cppreference.com
| 在标头 <span> 定义
|
||
| (1) | ||
| (C++20 起) (C++26 前) |
||
| |
(C++26 起) | |
| |
(2) | (C++20 起) |
| |
(3) | (C++20 起) |
| |
(4) | (C++20 起) |
| |
(5) | (C++20 起) |
为 span 提供下列推导指引。
1) 允许从迭代器-哨位对推导元素类型。在
EndOrSize 满足 integral-constant-like 时也允许推导静态尺度。(C++26 起)此重载只有在 It 满足 contiguous_iterator 时才会参与重载决议。2-4) 允许从内建数组与 std::array 推导静态长度。
示例
运行此代码
#include <array>
#include <cstddef>
#include <iomanip>
#include <iostream>
#include <span>
#include <string_view>
#include <vector>
void print(std::string_view rem = "", std::size_t size_of = 0, std::size_t extent = 0)
{
if (rem.empty())
{
std::cout << "name │ sizeof │ extent\n"
"─────┼────────┼────────\n";
return;
}
std::cout << std::setw(4) << rem << " │ " << std::setw(6) << size_of << " │ ";
if (extent == std::dynamic_extent)
std::cout << "dynamic";
else
std::cout << extent;
std::cout << '\n';
}
int main()
{
int a[]{1, 2, 3, 4, 5};
print();
std::span s1{std::begin(a), std::end(a)}; // 指引 (1)
print("s1", sizeof s1, s1.extent);
std::span s2{std::begin(a), 3}; // 指引 (1)
print("s2", sizeof s2, s2.extent);
#if __cplusplus > 202302L
std::span s3{std::begin(a), std::integral_constant<std::size_t, 2>{}}; // 指引 (1)
print("s3", sizeof s3, s3.extent);
#endif // C++26
std::span s4{a}; // 指引 (2)
print("s4", sizeof s4, s4.extent);
std::span<int> s5{a}; // 不使用指引,制作动态 span
print("s5", sizeof s5, s5.extent);
std::array arr{6, 7, 8};
std::span s6{arr}; // 指引 (3)
print("s6", sizeof s6, s6.extent);
s5[0] = 42; // OK, element_type 为 'int'
const std::array arr2{9, 10, 11};
std::span s7{arr2}; // 指引 (4)
print("s7", sizeof s7, s7.extent);
// s7[0] = 42; // 错误: element_type 为 'const int'
std::vector v{66, 69, 99};
std::span s8{v}; // 指引 (5)
print("s8", sizeof s8, s8.extent);
}
可能的输出:
name │ sizeof │ extent
─────┼────────┼────────
s1 │ 16 │ dynamic
s2 │ 16 │ dynamic
s3 │ 8 │ 2
s4 │ 8 │ 5
s5 │ 16 │ dynamic
s6 │ 8 │ 3
s7 │ 8 │ 3
s8 │ 16 │ dynamic