Недавно я получил предложения по использованию span<T>
в моем коде, или видел некоторые ответы здесь на сайте, которые используют span
х — якобы какой-то контейнер. Но — я не могу найти ничего подобного в стандартной библиотеке C ++.
Так что же это за таинственное span<T>
и почему (или когда) лучше использовать его, если он нестандартный?
span<T>
является:
struct { T * const ptr; size_t length; }
с кучей удобных методов.Ранее он был известен как array_view
а еще раньше как array_ref
.
Во-первых, когда не использовать это:
std::sort
, std::find_if
, std::copy
и все эти супер-общие шаблонные функции.Теперь для того, когда фактически использовать это:
использование
span<T>
(соответственно,span<const T>
) вместо отдельно стоящегоT*
(соответственноconst T*
) для которого у вас есть значение длины. Итак, замените функции, такие как:void read_into(int* buffer, size_t buffer_size);
с:
void read_into(span<int> buffer);
Ох, пролеты потрясающие! Используя span
…
означает, что вы можете работать с этой комбинацией указатель + длина / начало + конец указателя, как если бы вы работали с вычурным контейнером стандартной библиотеки, например:
for (auto& x : my_span) { /* do stuff */ }
std::find_if(my_span.begin(), my_span.end(), some_predicate);
… но без каких-либо накладных расходов большинство контейнерных классов.
позволяет компилятору иногда выполнять за вас больше работы. Например, это:
int buffer[BUFFER_SIZE];
read_into(buffer, BUFFER_SIZE);
становится так:
int buffer[BUFFER_SIZE];
read_into(buffer);
… который будет делать то, что вы хотели бы это сделать. Смотрите также Положение С.5.
является разумной альтернативой для прохождения const vector<T>&
к функциям, когда вы ожидаете, что ваши данные будут непрерывными в памяти. Больше не надо ругать могучих гуру C ++.
облегчает статический анализ, поэтому компилятор может помочь вам обнаружить глупые ошибки.
span
методы будут иметь некоторый код проверки границ внутри #ifndef NDEBUG
… #endif
)Там еще больше мотивации для использования span
с, которые вы могли бы найти в Основные принципы C ++ — но вы ловите дрейф
Он есть в стандартной библиотеке — но только на C ++ 20. Причина в том, что он все еще довольно новый в его нынешнем виде, задуманный в сочетании с Основные принципы C ++ Проект, который только формируется с 2015 года. (Хотя, как отмечают комментаторы, он имеет более раннюю историю.)
Это часть Основные руководящие принципыБиблиотека поддержки (GSL). Реализации:
gsl/span
span<T>
,Обратите внимание, что вы можете использовать его с более ранними версиями стандарта языка — C ++ 11 и C ++ 14, а не только с C ++ 17.
Дальнейшее чтение: Вы можете найти все детали и конструктивные соображения в окончательном официальном предложении до C ++ 17, P0122R7: span: безопасные границы для последовательностей объектов Нил Макинтош и Стефан Дж. Лававей. Это немного долго, хотя. Также в C ++ 20 изменилась семантика сравнения диапазонов эта короткая статья Тони ван Эрд).
Других решений пока нет …