@einpoklum fait un assez bon travail d'introduire quelle span
est sa réponse ici . Cependant, même après avoir lu sa réponse, il est facile pour quelqu'un qui ne connaît pas le domaine d'avoir toujours une séquence de questions de réflexion qui ne sont pas entièrement répondues, telles que les suivantes:
- Comment est un
span
différent d'un tableau C? Pourquoi ne pas simplement en utiliser un? Il semble que ce ne soit que l'un de ceux dont la taille est également connue ...
- Attendez, cela ressemble à un
std::array
, en quoi est-ce span
différent de cela?
- Oh, ça me rappelle, n'est-ce pas
std::vector
comme un std::array
aussi?
- Je suis tellement confus. :( Qu'est-ce qu'un
span
?
Alors, voici quelques précisions supplémentaires à ce sujet:
CITATION DIRECTE DE SA RÉPONSE - AVEC MES ADDITIONS EN GRAS :
Qu'Est-ce que c'est?
A span<T>
est:
- Une abstraction très légère d'une séquence contiguë de valeurs de type
T
quelque part en mémoire.
- Fondamentalement, une seule structure
{ T * ptr; std::size_t length; }
avec un tas de méthodes pratiques. (Remarquez que ceci est distinctement différent du std::array<>
fait que un span
permet des méthodes d'accesseur pratiques, comparables à std::array
, via un pointeur vers typeT
et longueur (nombre d'éléments) de type T
, alors qu'il std::array
s'agit d'un conteneur réel qui contient une ou plusieurs valeurs de type T
.)
- Un type sans propriétaire (c'est-à-dire un "type de référence" plutôt qu'un "type de valeur"): il n'alloue ni ne désalloue rien et ne maintient pas les pointeurs intelligents en vie.
Il était auparavant connu sous le nom de array_view
et même plus tôt array_ref
.
Ces parties audacieuses sont essentielles à la compréhension, alors ne les manquez pas ou ne les lisez pas! A span
n'est PAS un C-tableau de structures, ni un struct d'un C-tableau de type T
plus la longueur du tableau (ce serait essentiellement ce que le std::array
conteneur est), NI n'est-ce pas un C-tableau de structures de pointeurs à taper T
plus la longueur, mais c'est plutôt une structure unique contenant un seul pointeur à taperT
, et la longueur , qui est le nombre d'éléments (de type T
) dans le bloc de mémoire contigu vers lequel T
pointe le pointeur à taper ! De cette façon, la seule surcharge que vous avez ajoutée en utilisant unspan
sont les variables pour stocker le pointeur et la longueur, et toutes les fonctions d'accesseur de commodité que vous utilisez et qui le span
fournissent.
Il ne s'agit pas d'un std::array<>
parce que le std::array<>
alloue réellement de la mémoire pour le bloc contigu entier, et il n'est pas comme std::vector<>
parce qu'un std::vector
est fondamentalement juste un std::array
qui fait également une croissance dynamique (généralement doublant de taille) à chaque fois qu'il se remplit et que vous essayez d'ajouter quelque chose d'autre. . A std::array
est de taille fixe, et un span
ne gère même pas la mémoire du bloc il pointe, il seulement des points au bloc de mémoire, sait combien de temps le bloc de mémoire est, sait ce type de données est dans un C-tableau dans la mémoire et fournit des fonctions d'accesseur pratiques pour travailler avec les éléments de cette mémoire contiguë .
Il fait partie du standard C ++:
std::span
fait partie de la norme C ++ à partir de C ++ 20. Vous pouvez lire sa documentation ici: https://en.cppreference.com/w/cpp/container/span . Pour voir comment utiliser Google absl::Span<T>(array, length)
en C ++ 11 ou plus tard aujourd'hui , voir ci-dessous.
Descriptions sommaires et références clés:
std::span<T, Extent>
( Extent
= "le nombre d'éléments dans la séquence, ou std::dynamic_extent
s'il est dynamique". Une plage pointe simplement vers la mémoire et facilite l'accès, mais ne la gère PAS!):
- https://en.cppreference.com/w/cpp/container/span
std::array<T, N>
(remarquez qu'il a une taille fixeN
!):
- https://en.cppreference.com/w/cpp/container/array
- http://www.cplusplus.com/reference/array/array/
std::vector<T>
(augmente automatiquement la taille de façon dynamique si nécessaire):
- https://en.cppreference.com/w/cpp/container/vector
- http://www.cplusplus.com/reference/vector/vector/
Comment puis-je utiliser span
en C ++ 11 ou plus tard aujourd'hui ?
Google a open source leurs bibliothèques C ++ 11 internes sous la forme de leur bibliothèque "Abseil". Cette bibliothèque est destinée à fournir des fonctionnalités C ++ 14 à C ++ 20 et au-delà qui fonctionnent en C ++ 11 et versions ultérieures, afin que vous puissiez utiliser les fonctionnalités de demain dès aujourd'hui. Ils disent:
Compatibilité avec la norme C ++
Google a développé de nombreuses abstractions qui correspondent ou correspondent étroitement aux fonctionnalités incorporées dans C ++ 14, C ++ 17 et au-delà. L'utilisation des versions Abseil de ces abstractions vous permet d'accéder à ces fonctionnalités maintenant, même si votre code n'est pas encore prêt à vivre dans un monde post-C ++ 11.
Voici quelques ressources et liens clés:
- Site principal: https://abseil.io/
- https://abseil.io/docs/cpp/
- Référentiel GitHub: https://github.com/abseil/abseil-cpp
span.h
en-tête et absl::Span<T>(array, length)
classe de modèle: https://github.com/abseil/abseil-cpp/blob/master/absl/types/span.h#L189
std::span
a été proposé en 2017. Il s'applique au C ++ 17 ou au C ++ 20. Voir également P0122R5, vues span: sans limites pour les séquences d'objets . Voulez-vous vraiment cibler cette langue? Il faudra des années avant que les compilateurs ne rattrapent leur retard.