@einpoklum виконує досить непогану роботу, вказуючи, що тут span
є у своїй відповіді . Однак навіть після прочитання його відповіді, хтось із нових членів легко продовжує мати послідовність поточних питань, на які не відповідає повністю, таких як:
- Чим
span
відрізняється масив С? Чому б просто не скористатись одним із таких? Здається, що це просто одна з тих, хто також знає розмір ...
- Зачекайте, це звучить як
std::array
, чим span
відрізняється від цього?
- О, це мені нагадує, це теж не
std::vector
схоже std::array
?
- Я так розгубився. :( Що таке
span
?
Отже, ось дещо додаткової ясності щодо цього:
Пряма цитата його відповіді - з моїми доповненнями жирним шрифтом :
Що це?
A span<T>
це:
- Дуже легка абстракція суміжної послідовності значень типу
T
десь у пам'яті.
- В основному це одна структура
{ T * ptr; std::size_t length; }
з купою зручних методів. (Зауважте, це суттєво відрізняється від того, std::array<>
що span
дозволяє використовувати доступні методи доступу, порівнянні з std::array
, через вказівник на типT
і довжину (кількість елементів) типу T
, тоді std::array
як це фактичний контейнер, який містить одне або більше значень типу T
.)
- Невласний тип (тобто "тип посилання", а не "тип значення"): він ніколи нічого не виділяє і не передає і не підтримує розумні покажчики в живих.
Раніше він був відомий як array_view
і навіть раніше array_ref
.
Ці сміливі частини критично важливі для розуміння, тому не пропустіть їх і не перечитайте! A span
НЕ є C-масивом структур, не є структурою типу C-масиву T
плюс довжина масиву (це було б по суті те, що є std::array
контейнером ), NOR це C-масив структур покажчиків вводити T
плюс довжину, а скоріше це єдина структура, що містить один єдиний вказівник на типT
, і довжина , яка є кількістю елементів (типу T
) у суміжному блоці пам'яті, на який вказує вказівник T
! Таким чином, єдині накладні витрати, які ви додали за допомогоюspan
- це змінні для зберігання вказівника та довжини та будь-які функції аксесуара для зручності, якими ви користуєтеся span
.
Це UNLIKE a, std::array<>
оскільки std::array<>
насправді виділяє пам'ять на весь суміжний блок, і це UNLIKE, std::vector<>
тому що в std::vector
основному це просто std::array
те, що також робить динамічне зростання (як правило, подвоєння в розмірах) щоразу, коли воно заповнюється, і ви намагаєтесь додати щось інше до нього . std::array
Фіксується в розмірі, і навіть не управління пам'яттю блоку він вказує, що тільки вказує на блок пам'яті, знає , як довго блок пам'яті, знає , який тип даних в C-масиву в пам’яті та забезпечує зручні функції аксесуара для роботи з елементами цієї суміжної пам’яті .span
Він є частиною стандарту C ++:
std::span
є частиною стандарту C ++ станом на C ++ 20. Ви можете прочитати його документацію тут: https://en.cppreference.com/w/cpp/container/span . Щоб дізнатися , як використовувати Google, absl::Span<T>(array, length)
в C ++ 11 або пізнішої версії сьогодні , дивіться нижче.
Зведені описи та основні посилання:
std::span<T, Extent>
( Extent
= "кількість елементів у послідовності, або std::dynamic_extent
якщо динамічна". Проміжок просто вказує на пам'ять і полегшує доступ, але НЕ управляє ним!):
- https://en.cppreference.com/w/cpp/container/span
std::array<T, N>
(зауважте, він має фіксований розмір N
!):
- https://en.cppreference.com/w/cpp/container/array
- http://www.cplusplus.com/reference/array/array/
std::vector<T>
(автоматично динамічно збільшується в розмірах)
- https://en.cppreference.com/w/cpp/container/vector
- http://www.cplusplus.com/reference/vector/vector/
Як я можу використовувати span
в C ++ 11 або пізнішої версії сьогодні ?
Google відкрив свої внутрішні C ++ 11 бібліотеки у вигляді їхньої бібліотеки "Abseil". Ця бібліотека призначена для надання C ++ 14 до C ++ 20 і більше функцій, які працюють у C ++ 11 і пізніших версіях, щоб сьогодні можна було використовувати функції завтра. Вони кажуть:
Сумісність зі стандартом C ++
Google розробив багато абстракцій, які відповідають або суворо відповідають можливостям, включеним у C ++ 14, C ++ 17 і більше. Використання Abseil версій цих абстракцій дозволяє вам отримати доступ до цих функцій зараз, навіть якщо ваш код ще не готовий до життя в світі C ++ 11.
Ось декілька основних ресурсів та посилань:
- Основний сайт: https://abseil.io/
- https://abseil.io/docs/cpp/
- Репозиторій GitHub: https://github.com/abseil/abseil-cpp
span.h
заголовок та absl::Span<T>(array, length)
клас шаблонів: https://github.com/abseil/abseil-cpp/blob/master/absl/types/span.h#L189
std::span
було запропоновано у 2017 році. Це стосується C ++ 17 або C ++ 20. Також див. P0122R5, span: безпечні види для послідовностей об'єктів . Ви дійсно хочете орієнтуватися на цю мову? Минуть роки, перш ніж компілятори наздогнать.