@einpoklum fa un ottimo lavoro nel presentare ciò che a span
è nella sua risposta qui . Tuttavia, anche dopo aver letto la sua risposta, è facile per qualcuno che è nuovo avere una sequenza di domande sul flusso di pensiero a cui non è stata data una risposta completa, come le seguenti:
- In che modo è
span
diverso da un array C? Perché non usare solo uno di quelli? Sembra che sia solo uno di quelli con le dimensioni conosciute ...
- Aspetta, sembra un
std::array
, come è span
diverso da quello?
- Oh, questo mi ricorda, non è un
std::vector
po ' std::array
troppo?
- Sono così confuso. :( Che cos'è un
span
?
Quindi, ecco qualche ulteriore chiarimento al riguardo:
PREVENTIVO DIRETTO DELLA SUA RISPOSTA - CON LE MIE AGGIUNTE IN GRASSETTO :
Che cos'è?
A span<T>
è:
- Un'astrazione molto leggera di una sequenza contigua di valori di tipo
T
da qualche parte nella memoria.
- Fondamentalmente una singola struttura
{ T * ptr; std::size_t length; }
con un sacco di metodi di convenienza. (Si noti che questo è nettamente diverso dal std::array<>
perché span
consente metodi di accesso facilitato, comparabili a std::array
, tramite un puntatore al tipoT
e alla lunghezza (numero di elementi) del tipo T
, mentre std::array
è un contenitore reale che contiene uno o più valori di tipo T
.)
- Un tipo non proprietario (ovvero un "tipo di riferimento" anziché un "tipo di valore"): non alloca né distribuisce mai nulla e non mantiene in vita i puntatori intelligenti.
In precedenza era noto come array_view
e anche prima array_ref
.
Quelle parti audaci sono fondamentali per la comprensione di qualcuno, quindi non perderle o fraintenderle! A span
NON è un array C di strutture, né è una struttura di un array C di tipo T
più la lunghezza dell'array (questo sarebbe essenzialmente quello che è il std::array
contenitore ), NOR è un array C di strutture di puntatori digitare T
più la lunghezza, ma piuttosto è una singola struttura contenente un singolo puntatore da digitareT
e la lunghezza , che è il numero di elementi (di tipo T
) nel blocco di memoria contiguo a cui T
punta il puntatore da digitare ! In questo modo, l'unico sovraccarico che hai aggiunto utilizzando aspan
sono le variabili per memorizzare il puntatore e la lunghezza e tutte le funzioni accessor di convenienza utilizzate che span
forniscono.
Questo è UNLIKE a std::array<>
perché std::array<>
effettivamente alloca memoria per l'intero blocco contiguo, ed è UNLIKE std::vector<>
perché a std::vector
è fondamentalmente solo uno std::array
che fa anche crescere dinamicamente (di solito raddoppiando di dimensioni) ogni volta che si riempie e si tenta di aggiungere qualcos'altro ad esso . A ha std::array
dimensioni fisse e a span
non gestisce nemmeno la memoria del blocco a cui punta, punta solo al blocco di memoria, sa quanto è lungo il blocco di memoria, sa quale tipo di dati è in un array C nella memoria e offre comode funzioni di accesso per lavorare con gli elementi in quella memoria contigua .
Si è parte dello standard C ++:
std::span
fa parte dello standard C ++ come C ++ 20. Puoi leggere la sua documentazione qui: https://en.cppreference.com/w/cpp/container/span . Per sapere come utilizzare Google absl::Span<T>(array, length)
in C ++ 11 o versioni successive , vedere di seguito.
Descrizioni riepilogative e riferimenti chiave:
std::span<T, Extent>
( Extent
= "il numero di elementi nella sequenza, o std::dynamic_extent
se dinamico". Uno span punta solo alla memoria e ne facilita l'accesso, ma NON lo gestisce!):
- https://en.cppreference.com/w/cpp/container/span
std::array<T, N>
(nota che ha una dimensione fissaN
!):
- https://en.cppreference.com/w/cpp/container/array
- http://www.cplusplus.com/reference/array/array/
std::vector<T>
(cresce automaticamente in modo dinamico nelle dimensioni necessarie):
- https://en.cppreference.com/w/cpp/container/vector
- http://www.cplusplus.com/reference/vector/vector/
Come posso usare oggi span
in C ++ 11 o versioni successive ?
Google ha aperto le proprie librerie C ++ 11 interne sotto forma della libreria "Abseil". Questa libreria ha lo scopo di fornire da C ++ 14 a C ++ 20 e oltre funzionalità che funzionano in C ++ 11 e versioni successive, in modo da poter utilizzare le funzionalità di domani, oggi. Dicono:
Compatibilità con lo standard C ++
Google ha sviluppato molte astrazioni che corrispondono o coincidono strettamente con le funzioni incorporate in C ++ 14, C ++ 17 e oltre. L'uso delle versioni Abseil di queste astrazioni ti consente di accedere a queste funzionalità ora, anche se il tuo codice non è ancora pronto per la vita in un mondo post C ++ 11.
Ecco alcune risorse e collegamenti chiave:
- Sito principale: https://abseil.io/
- https://abseil.io/docs/cpp/
- Repository GitHub: https://github.com/abseil/abseil-cpp
span.h
intestazione e absl::Span<T>(array, length)
classe modello: https://github.com/abseil/abseil-cpp/blob/master/absl/types/span.h#L189
std::span
è stato proposto nel 2017. Si applica a C ++ 17 o C ++ 20. Vedi anche P0122R5, span: viste senza limiti per sequenze di oggetti . Vuoi davvero scegliere come target quella lingua? Ci vorranno anni prima che i compilatori raggiungano.