Step 6 of 7
std::span
std::span<T> (from <span>) is to arrays what string_view is to strings: a non-owning view of contiguous elements, just a pointer and a count. One function taking a span accepts a C array, a std::array or a std::vector, with no copying and no templates.
#include <array>
#include <iostream>
#include <span>
#include <vector>
double mean(std::span<const double> xs) {
double s = 0;
for (double x : xs) s += x;
return xs.empty() ? 0 : s / xs.size();
}
void zero_out(std::span<int> xs) { // non-const span: can modify
for (int& x : xs) x = 0;
}
int main() {
double c_array[] = {1, 2, 3, 4};
std::array<double, 2> arr = {10, 20};
std::vector<double> vec = {5, 5, 5, 9};
std::cout << mean(c_array) << " " << mean(arr) << " " << mean(vec) << "\n";
std::span<const double> all(vec);
std::cout << mean(all.subspan(1, 2)) << " " << mean(all.last(1)) << "\n";
std::vector<int> ids = {7, 8, 9, 10};
zero_out(std::span(ids).first(2));
for (int id : ids) std::cout << id << " ";
std::cout << "\n";
}
2.5 15 6
5 9
0 0 9 10
How it works
std::span<const double>means "a view of doubles I won't change".std::span<int>allows writing through it.subspan(offset, count),first(n)andlast(n)make smaller spans in O(1). No elements are copied.- A span remembers its size, unlike the pointer-plus-length pairs from C. So
for (double x : xs)just works.
What else modern C++ added
Two big C++20 features aren't practiced in this course, and you'll meet them in newer codebases:
- Modules (
export module geometry;andimport geometry;) replace#include's text pasting with compiled interfaces, which builds faster and stops macros leaking between files. C++23 addedimport std;for the whole standard library. Compiler and build-tool support took years to mature, so most existing code still uses headers. - Coroutines (
co_await,co_yield,co_return) are functions that can pause and later resume, used for asynchronous networking and for generators. The language provides the machinery, and you normally use them through a library (C++23 addedstd::generator).
C++23 also brought std::expected and std::print. A new standard comes out every three years, and C++26 is the next.
Your task: best window sum
The simple way: for each start i from 0 to xs.size() - k, sum xs.subspan(i, k) and keep the best. That's O(n * k).
The sliding window way is O(n): sum the first k elements, then for each step right, add the element entering the window and subtract the one leaving it (sum += xs[i] - xs[i - k]). Start best from the first window's sum, not 0, because every value might be negative.
Your turn: write int max_window(std::span<const int> xs, std::size_t k) that returns the largest sum of k consecutive elements. Use subspan or a sliding window. Assume 1 <= k <= xs.size().