第9.10章: span 与 index_span
概述
::fast_io::span<T> 与 ::fast_io::index_span<T, N> 都是对连续内存的非拥有视图。它们不分配也不释放内存 — 只是指向由别处拥有的数据。
1. span<T>
span 就是一个指针加一个大小。把它用作函数参数类型,就能在不复制的情况下接受任何连续容器:
#include <fast_io_dsal/span.h>
#include <fast_io_dsal/vector.h>
#include <fast_io_dsal/array.h>
#include <fast_io.h>
// Accepts vector, array, span, C-array - anything contiguous
void print_all(::fast_io::span<::std::size_t const> data) {
for (auto const& e : data) {
::fast_io::io::println(e);
}
}
int main() {
::fast_io::vector<::std::size_t> v{1zu, 2zu, 3zu};
::fast_io::array<::std::size_t, 3zu> a{4zu, 5zu, 6zu};
print_all(::fast_io::span(v.data(), v.size()));
print_all(::fast_io::span(a.data(), a.size()));
}
子 span 操作
::fast_io::span<::std::size_t> sp(vec.data(), vec.size());
auto first_half = sp.subspan_front(sp.size() / 2);
auto last_quarter = sp.subspan_back(sp.size() / 4);
auto middle = sp.subspan(1zu, 3zu); // 3 elements starting at index 1
// Unchecked variants for performance-critical code
auto fast_sub = sp.subspan_front_unchecked(5zu);
2. index_span<T, N>
index_span 是编译期大小固定的 span。大小 N 是类型的一部分,因此编译器可以校验它:
#include <fast_io_dsal/index_span.h>
#include <fast_io.h>
// Requires exactly 4 elements
void process_quad(::fast_io::index_span<double, 4zu> quad) {
for (::std::size_t i{}; i != quad.size(); ++i) {
::fast_io::io::println(quad[i]);
}
}
int main() {
double coords[]{1.0, 2.0, 3.0, 4.0};
::fast_io::index_span<double, 4zu> ispan(
::fast_io::containers::index_unchecked,
coords
);
process_quad(ispan);
}
要点
span<T>是非拥有视图(指针 + 动态大小)。index_span<T, N>的大小在编译期固定。- 两者都只是一个指针加一个大小,没有其他额外负担。
- 把
span用作函数参数,即可接受任何连续容器。 - 子 span 操作:
subspan_front()、subspan_back()、subspan()。