← Назад к вопросам

Что такое std::span?

1.8 Middle🔥 131 комментариев
#Язык C++

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI30 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

std::span — просмотр на смежные элементы памяти

std::span — это шаблонный класс (с C++20), который предоставляет non-owning представление (view) на смежный блок данных. Это легковесный объект, содержащий указатель и размер, без выделения памяти.

Основное предназначение

std::span решает проблему передачи массивов в функции:

  • Раньше: передавали указатель + размер отдельно, или полагались на nullptr-terminator
  • Теперь: передаём один std::span, содержащий оба параметра

Синтаксис и примеры

#include <span>
#include <vector>
#include <array>

// Создание span из обычного массива
int arr[] = {1, 2, 3, 4, 5};
std::span<int> sp1(arr);  // size выведется как 5

// Из std::vector
std::vector<int> vec = {10, 20, 30};
std::span<int> sp2(vec);

// Из std::array
std::array<int, 3> arr3 = {100, 200, 300};
std::span<int> sp3(arr3);

// С явным размером (подмножество)
std::span<int> sp4(arr, 3);  // только первые 3 элемента

// Функция, принимающая span
void process(std::span<int> data) {
    for (int val : data) {
        std::cout << val << " ";
    }
}

process(sp1);  // Работает с массивом
process(sp2);  // Работает с vector
process(sp3);  // Работает с array

Ключевые особенности

1. Non-owning (не владеет памятью)

  • span не выделяет память и не очищает её
  • Просто ссылается на существующие данные
  • Жизненный цикл данных контролируется владельцем

2. Лёгкий вес

std::span<int> sp;  // sizeof = 16 байт (указатель + size)

Намного компактнее, чем std::vector

3. Compile-time размер (опционально)

std::span<int, 5> fixed_sp(arr);  // Размер известен на compile-time
std::span<int> dynamic_sp(arr);   // Размер известен на runtime

4. Подмножество (slicing)

std::span<int> sub = sp.subspan(1, 3);  // Элементы с индекса 1, длина 3

Преимущества

  • Единый интерфейс: функция принимает один параметр вместо (ptr, size)
  • Безопасность: bounds-checking операции (в debug)
  • Производительность: нулевые overhead, полностью inlineable
  • Гибкость: работает с массивами, vector, array, custom контейнерами

Когда использовать

// Хорошо для span
void sort_array(std::span<int> data);
void fill_buffer(std::span<std::byte> buffer);
void process_matrix(std::span<const double> row);

// Менее подходяще
std::span<std::complex_object> sp;  // Если нужна сложная семантика

Ограничения

  • Не гарантирует стабильность указателя (особенно с vector — может переделокироваться)
  • Нельзя "расширить" span в runtime
  • С C++20 и выше (поддержка зависит от компилятора)

std::span — это modern C++ tool для безопасной и элегантной работы с буферами и массивами.