@einpoklum неплохо показывает, что span
есть в его ответе . Тем не менее, даже после прочтения его ответа, для новичков в спанах будет легко иметь последовательность вопросов для обсуждения, на которые нет полного ответа, таких как следующее:
- Чем
span
отличается от массива C? Почему бы просто не использовать один из них? Похоже, что это только один из известных размеров ...
- Подождите, это звучит как
std::array
, как span
отличается от этого?
- О, это напоминает мне, не
std::vector
как у std::array
тоже?
- Я весьма озадачен. Что это
span
?
Итак, вот дополнительная ясность по этому поводу:
ПРЯМАЯ ЦИТАТА ЕГО ОТВЕТА - С МОИМИ ДОПОЛНЕНИЯМИ, выделенными жирным шрифтом :
Что это?
А span<T>
это:
- Очень легкая абстракция непрерывной последовательности значений типа
T
где-то в памяти.
- В основном единственная структура
{ T * ptr; std::size_t length; }
с кучей удобных методов. (Обратите внимание, что это явно отличается от того, std::array<>
что a 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<>
потому что a std::vector
в основном просто a, std::array
который также выполняет динамический рост (обычно удваивается в размере) каждый раз, когда он заполняется, и вы пытаетесь добавить что-то еще к нему , A std::array
имеет фиксированный размер, и a span
даже не управляет памятью блока, на который он указывает, он просто указывает на блок памяти, знает, как долго находится блок памяти, знает, какой тип данных находится в C-массиве в памяти, и предоставляет удобные функции доступа для работы с элементами в этой смежной памяти .
Она является частью 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: безопасные для границ представления для последовательностей объектов . Вы действительно хотите нацелиться на этот язык? Пройдут годы, прежде чем компиляторы догонят.