Заметки по языку с и с++

std::span в C++20: невладеющий вид на непрерывную последовательность

Что представляет собой std::span

std::span из C++20 — небольшой объект-представление: он хранит указатель на первый элемент и размер последовательности, но не владеет памятью. Это удобно для функций, которым нужен массив данных без привязки к конкретному контейнеру.

#include <span>
#include <vector>
#include <cstddef>

std::size_t sum(std::span<const int> values)
{
    std::size_t result = 0;
    for (int value : values)
        result += static_cast<std::size_t>(value);
    return result;
}

std::vector<int> data{1, 2, 3};
auto total = sum(data);

Параметр принимает также C-массив и std::array, если элементы расположены непрерывно. Константный элементный тип позволяет читать данные, не меняя исходный контейнер.

Срок жизни важнее удобства

Поскольку span не владеет памятью, исходный контейнер должен оставаться живым и не перераспределять память, пока используется представление. Не возвращайте span на локальный массив и не сохраняйте его дольше владельца. Для обычной функции-потребителя это безопасно: span передаётся, используется сразу и не переживает вызов.

Используйте size() и проверяйте границы индексов так же внимательно, как для любого диапазона. Для API, которому требуется собственная копия данных, span не подходит — там нужен контейнер-владелец.