@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: безопасные для границ представления для последовательностей объектов . Вы действительно хотите нацелиться на этот язык? Пройдут годы, прежде чем компиляторы догонят.