@einpoklum hat einen ziemlich guten Job einzuführen , was eine span
ist hier in seiner Antwort . Doch auch nach seiner Antwort zu lesen, ist es einfach für jemanden neu in Spannweiten noch eine Folge von Stream-of-Gedanken Fragen hat , die nicht vollständig beantwortet werden, wie die folgenden:
- Wie
span
unterscheidet sich ein C-Array? Warum nicht einfach eine davon verwenden? Es scheint, als wäre es nur einer von denen mit der bekannten Größe ...
- Warten Sie, das klingt wie ein
std::array
, wie unterscheidet sich ein span
davon?
- Oh, das erinnert mich, ist kein
std::vector
wie ein std::array
zu?
- Ich bin so verwirrt. :( Was ist ein
span
?
Hier ist eine zusätzliche Klarheit dazu:
DIREKTES ZITAT SEINER ANTWORT - MIT MEINEN ERGÄNZUNGEN IN Fettdruck :
Was ist es?
A span<T>
ist:
- Eine sehr leichte Abstraktion einer zusammenhängenden Folge von Werten vom Typ
T
irgendwo im Speicher.
- Grundsätzlich eine einzelne Struktur
{ T * ptr; std::size_t length; }
mit einer Reihe von praktischen Methoden. (Beachten Sie, dass sich dies deutlich davon unterscheidet, std::array<>
weil a span
Convenience-Accessor-Methoden ermöglicht, die mit std::array
einem Zeiger auf TypT
und Länge (Anzahl der Elemente) des Typs vergleichbar sind T
, während std::array
es sich um einen tatsächlichen Container handelt, der einen oder mehrere Werte des Typs enthält T
.)
- Ein nicht besitzender Typ (dh ein "Referenztyp" anstelle eines "Werttyps"): Er weist niemals etwas zu oder gibt die Zuordnung auf und hält intelligente Zeiger nicht am Leben.
Es war früher als array_view
und noch früher als bekannt array_ref
.
Diese fett Teile sind kritisch zu einem Verständnis, also nicht verpassen sie oder sie falsch verstanden! A span
ist KEIN C-Array von Strukturen, noch ist es eine Struktur eines C-Arrays vom Typ T
plus der Länge des Arrays (dies wäre im Wesentlichen das, was der std::array
Container ist), NOR ist es ein C-Array von Strukturen von Zeigern zu tippen T
plus die Länge, sondern es ist eine einzelne Struktur, die einen einzelnen zuT
tippenden Zeiger enthält , und die Länge , die die Anzahl der Elemente (vom Typ T
) in dem zusammenhängenden Speicherblock ist, auf den der zu tippende Zeiger T
zeigt! Auf diese Weise erhalten Sie den einzigen Overhead, den Sie mithilfe von a hinzugefügt habenspan
sind die Variablen zum Speichern des Zeigers und der Länge sowie alle von Ihnen verwendeten praktischen Zugriffsfunktionen span
.
Dies ist im Gegensatz zu einem , std::array<>
weil die std::array<>
tatsächlich zuteilt Speicher für den gesamten zusammenhängenden Block, und es ist nicht wie, std::vector<>
weil ein std::vector
im Grunde ist eine gerade , std::array
dass auch tut dynamisch wachsen ( in der Regel in der Größe verdoppelt) jedes Mal , es füllt sich , und Sie versuchen , etwas anderes , um es hinzuzufügen . A std::array
hat eine feste Größe und a span
verwaltet nicht einmal den Speicher des Blocks, auf den es zeigt. Es zeigt nur auf den Speicherblock, weiß, wie lang der Speicherblock ist und weiß, welcher Datentyp in einem C-Array enthalten ist im Speicher und bietet praktische Zugriffsfunktionen, um mit den Elementen in diesem zusammenhängenden Speicher zu arbeiten .
Es ist Teil des C ++ - Standards:
std::span
ist Teil des C ++ - Standards ab C ++ 20. Sie können die Dokumentation hier lesen: https://en.cppreference.com/w/cpp/container/span . Informationen zur Verwendung von Google absl::Span<T>(array, length)
in C ++ 11 oder höher finden Sie weiter unten.
Zusammenfassende Beschreibungen und wichtige Referenzen:
std::span<T, Extent>
( Extent
= "die Anzahl der Elemente in der Sequenz oder std::dynamic_extent
wenn dynamisch". Ein Bereich zeigt nur auf den Speicher und erleichtert den Zugriff, verwaltet ihn jedoch NICHT!):
- https://en.cppreference.com/w/cpp/container/span
std::array<T, N>
(Beachten Sie, dass es eine feste Größe hat N
!):
- https://en.cppreference.com/w/cpp/container/array
- http://www.cplusplus.com/reference/array/array/
std::vector<T>
(wächst bei Bedarf automatisch dynamisch an Größe):
- https://en.cppreference.com/w/cpp/container/vector
- http://www.cplusplus.com/reference/vector/vector/
Wie kann ich span
in C ++ 11 oder später heute ?
Google hat seine internen C ++ 11-Bibliotheken in Form seiner "Abseil" -Bibliothek als Open-Source-Version bereitgestellt. Diese Bibliothek soll Funktionen von C ++ 14 bis C ++ 20 und darüber hinaus bereitstellen, die in C ++ 11 und höher funktionieren, sodass Sie die Funktionen von morgen noch heute nutzen können. Man sagt:
Kompatibilität mit dem C ++ Standard
Google hat viele Abstraktionen entwickelt, die den in C ++ 14, C ++ 17 und darüber hinaus enthaltenen Funktionen entsprechen oder genau entsprechen. Mit den Abseil-Versionen dieser Abstraktionen können Sie jetzt auf diese Funktionen zugreifen, auch wenn Ihr Code in einer Post-C ++ 11-Welt noch nicht lebensbereit ist.
Hier sind einige wichtige Ressourcen und Links:
- Hauptseite: https://abseil.io/
- https://abseil.io/docs/cpp/
- GitHub-Repository: https://github.com/abseil/abseil-cpp
span.h
Header und absl::Span<T>(array, length)
Vorlagenklasse: https://github.com/abseil/abseil-cpp/blob/master/absl/types/span.h#L189
std::span
wurde 2017 vorgeschlagen. Es gilt für C ++ 17 oder C ++ 20. Siehe auch P0122R5, span: Grenzen-sichere Ansichten für Sequenzen von Objekten . Möchten Sie diese Sprache wirklich ansprechen? Es wird Jahre dauern, bis die Compiler aufholen.