A span<T>
c'est ça :
template <typename T>
struct span
{
T * ptr_to_array; // pointer to a contiguous C-style array of data
// (which memory is NOT allocated or deallocated
// by the span)
std::size_t length; // number of elements in the array
// Plus a bunch of constructors and convenience accessor methods here
}
Il s'agit d'une enveloppe légère autour d'un tableau de style C, préférée par les développeurs C++ chaque fois qu'ils utilisent des bibliothèques C et qu'ils veulent les envelopper avec un conteneur de données de style C++ pour la "sécurité des types", l'"esprit C++" et la "convivialité".)
Pour aller plus loin :
@einpoklum fait un très bon travail pour présenter ce qu'est un span
est dans sa réponse ici . Cependant, même après avoir lu sa réponse, il est facile pour une personne novice en matière de spans d'avoir encore une série de questions à l'emporte-pièce auxquelles il n'est pas possible de répondre complètement, telles que les suivantes :
- Comment un
span
différent d'un tableau C ? Pourquoi ne pas simplement utiliser l'un d'entre eux ? Il semble que c'est juste un de ceux-là avec la taille connue aussi...
- Attends, ça ressemble à un
std::array
comment un span
différent de celui-là ?
- Oh, ça me fait penser, n'est-ce pas un
std::vector
comme un std::array
aussi ?
- Je suis tellement confus. :( Qu'est-ce qu'un
span
?
Voici donc quelques éclaircissements supplémentaires à ce sujet :
CITATION DIRECTE DE SA RÉPONSE - AVEC MES ADDITIONS et commentaires entre parenthèses en caractères gras et Je souligne en italique :
Qu'est-ce que c'est ?
A span<T>
est :
- Une abstraction très légère d'un séquence de valeurs contiguës de type
T
quelque part dans la mémoire.
- En gros, un simple struct
{ T * ptr; std::size_t length; }
avec un tas de méthodes pratiques. (Notez que ceci est très différent de std::array<>
car un span
permet des méthodes d'accès pratiques, comparables à std::array
par l'intermédiaire d'un pointeur vers le type T
et longueur (nombre d'éléments) de type T
alors que std::array
est un conteneur réel qui contient un ou plusieurs valeurs de type T
.)
- A type de non-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 jamais rien et ne garde pas les pointeurs intelligents en vie.
Il était autrefois connu sous le nom de array_view
et même plus tôt comme array_ref
.
Ces parties en gras sont critique à la compréhension de chacun, alors ne les ratez pas et ne les lisez pas mal ! A span
n'est PAS un tableau C de structs, ni un struct d'un tableau C de type T
plus la longueur du tableau (c'est essentiellement ce que fait l'option std::array
conteneur est), NOR est un tableau C de structs de pointeurs de type T
plus la longueur, mais il s'agit plutôt d'une simple struct contenant un seul pointeur vers le type T
et le longueur qui est le nombre d'éléments (de type T
) dans le bloc de mémoire contigu que le pointeur du type T
pointe ! De cette façon, le seul surcoût que vous avez ajouté en utilisant un fichier span
sont les variables permettant de stocker le pointeur et la longueur, ainsi que toutes les fonctions d'accès de commodité que vous utilisez et qui sont utilisées par l'utilisateur. span
fournit.
Cela n'a rien à voir avec un std::array<>
parce que le std::array<>
alloue en fait de la mémoire pour le bloc contigu entier, et c'est UNLIKE std::vector<>
car un std::vector
est en fait juste un std::array
qui fait aussi croissance dynamique (dont la taille double généralement) chaque fois qu'il se remplit et que vous essayez d'y ajouter quelque chose. A std::array
est de taille fixe, et a span
ne gère même pas la mémoire du bloc vers lequel il pointe, il se contente de pointer vers le bloc de mémoire, de connaître la longueur du bloc de mémoire, de savoir quel type de données se trouve dans un tableau C de la mémoire et de fournir des fonctions d'accès pratiques pour travailler avec les éléments de cette mémoire contiguë. .
Il est qui fait partie de la norme 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 savoir comment utiliser les services de Google absl::Span<T>(array, length)
en C++11 ou plus 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
si dynamique". Une portée juste Les points suivants la mémoire et la rend facile d'accès, mais ne la gère PAS !) :
- https://en.cppreference.com/w/cpp/container/span
-
std::array<T, N>
(remarquez qu'il y a un Correction de taille N
!) :
- https://en.cppreference.com/w/cpp/container/array
- http://www.cplusplus.com/reference/array/array/
-
std::vector<T>
(dont la taille augmente automatiquement et dynamiquement 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 aujourd'hui ?
Google a mis en libre accès ses bibliothèques internes C++11 sous la forme de sa bibliothèque "Abseil". Cette bibliothèque est destinée à fournir des fonctionnalités C++14 à C++20 et au-delà qui fonctionnent dans C++11 et plus, afin que vous puissiez utiliser les fonctionnalités de demain, aujourd'hui. C'est ce qu'ils disent :
Compatibilité avec la norme C++
Google a développé de nombreuses abstractions qui correspondent ou s'approchent des 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 dè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/
- Dépôt GitHub : https://github.com/abseil/abseil-cpp
-
span.h
l'en-tête, et absl::Span<T>(array, length)
classe modèle : https://github.com/abseil/abseil-cpp/blob/master/absl/types/span.h#L153
Autres références :
- Structures avec variables modèles en C++
- Wikipédia : Classes C++
- visibilité par défaut des membres des classes/structures C++
En rapport :
- [une autre de mes réponses sur les modèles et les travées]. Comment faire une travée de travées
1 votes
std::span
a été proposé en 2017. Elle s'applique à C++17 ou C++20. Voir aussi P0122R5, span : vues sécurisées par les limites pour les séquences d'objets . Voulez-vous vraiment cibler ce langage ? Il faudra des années avant que les compilateurs ne rattrapent leur retard.6 votes
@jww : les span's sont tout à fait utilisables avec C++11... comme
gsl::span
plutôt questd::span
. Voir aussi ma réponse ci-dessous.0 votes
Également documenté sur cppreference.com : fr.cppreference.com/w/cpp/container/span
3 votes
@KeithThompson : Pas en 2017, ce n'était pas...
1 votes
@jww Tous les compilateurs supportent std::span<> maintenant en mode C++20. Et span est disponible dans de nombreuses librairies tierces. Vous aviez raison - cela fait des années : 2 ans pour être précis.