Ce face std::span
std::span ține doar un pointer și o lungime: vede elementele altui container, fără să le copieze și fără să le dețină. Este parametrul ideal pentru o funcție care trebuie să lucreze cu „un șir de elemente”, oricum ar fi stocate: aceeași funcție f(std::span<const int>) primește un std::vector<int>, un std::array sau un tablou C.
Cu std::span<const T> funcția doar citește; cu std::span<T> poate modifica elementele originale. first(n), last(n) și subspan(poz, n) dau bucăți din fereastră, tot fără copiere. Are size(), empty(), operator[], front, back, data și se poate parcurge cu for.
Pentru că nu deține memoria, un span este valid doar cât timp există containerul și cât timp acesta nu se realocă.
Parametri
| Parametru | Descriere |
|---|---|
T |
Tipul elementelor (const T pentru acces doar la citire). |
N |
Opțional: dimensiunea fixă, cunoscută la compilare. |
Ce returnează
Un obiect span (o vedere asupra elementelor).
Exemple
Exemplul 1: O funcție pentru orice container continuu
#include <array>
#include <print>
#include <span>
#include <vector>
double medie(std::span<const double> valori) {
double suma = 0;
for (double v : valori) {
suma += v;
}
return valori.empty() ? 0 : suma / static_cast<double>(valori.size());
}
int main() {
std::vector<double> note{9.5, 8.0, 10.0};
std::array<double, 4> temperaturi{12.0, 15.5, 11.0, 9.5};
double tablou_c[] = {1.0, 2.0};
std::println("{:.2f}", medie(note));
std::println("{:.2f}", medie(temperaturi));
std::println("{:.2f}", medie(tablou_c));
}
Rezultat
9.17
12.00
1.50
Exemplul 2: Bucăți dintr-un vector și modificare prin span
#include <print>
#include <span>
#include <vector>
void dubleaza(std::span<int> s) {
for (int& x : s) {
x *= 2;
}
}
int main() {
std::vector<int> v{1, 2, 3, 4, 5, 6, 7, 8};
std::span<int> tot(v);
std::println("primele 3: {}", tot.first(3));
std::println("ultimele 2: {}", tot.last(2));
std::println("subspan(2,4): {}", tot.subspan(2, 4));
dubleaza(tot.subspan(4)); // modifică elementele originale, de la poziția 4
std::println("vectorul: {}", v);
}
Rezultat
primele 3: [1, 2, 3]
ultimele 2: [7, 8]
subspan(2,4): [3, 4, 5, 6]
vectorul: [1, 2, 3, 4, 10, 12, 14, 16]
Greșeli frecvente
- Creezi un span dintr-un vector temporar sau păstrezi un span după
push_back. Span-ul indică memorie eliberată (comportament nedefinit). - Folosești
std::span<int>ca parametru pentru o funcție care doar citește și nu poți trimite unconst std::vector<int>. Foloseștestd::span<const int>. - Încerci să creezi un span dintr-un
std::listsaustd::deque. Span-ul cere elemente consecutive în memorie; aceste containere nu le au.
Comenzi înrudite
std::vector::data: Returnează un pointer la primul element al vectorului, pentru funcții care lucrează cu tablouri C.std::array: Tablou cu dimensiune fixă, cunoscută la compilare, cu interfața unui container (size, at, begin, end).std::vector: Tabloul dinamic din C++: ține elementele unul după altul în memorie și își mărește singur dimensiunea.std::string_view: Vedere doar pentru citire asupra unui text existent, fără copiere; se poate micșora la capete.