Почему std::span это указатель + размер, а не два итератора

Похоже, что std::span в С ++20 определяется аналогично

template<class T>
class span
     {
     T* begin;
     size_t count;
     };

И нет

template<class Iter>
class span
     {
     Iter begin;
     Iter end;
     };

что является более общим (работает с std::list, std::map и т. д.)?

1 ответ

Весь смысл std::span<T> должен быть взгляд на смежные данные. pair<T*, size_> (или что-то вроде этого) является правильным способом представления этого взгляда. Вы не можете иметь std::span это вид на std::list или std::mapтак что нет смысла придумывать способ представить это. Дело в том, чтобы быть общим, словарным типом, чтобы просто принимать непрерывные данные.

Это тоже очень важно span эффективно стирается. span<int> может относиться к int[20] или vector<int> или int[] который динамически распределяется где-то или llvm::SmallVector<int> или... Неважно, откуда это берутся, у вас просто есть один тип: "вид на несколько смежных ints".

Правда, что pair<Iter, Iter> (или, в более общем pair<Iter, Sentinel>) является более общим представлением, которое будет работать для большего количества контейнеров. В C++20 есть такая вещь, она называется std::ranges::subrange<I, S>, Но обратите внимание, что у нас нет аспекта стирания типа... subrange через map<K, V> будет иметь другой тип, чем subrange через другой контейнер с тем же value_type, любить list<pair<K const, V>> или же vector<pair<K const, V>> или же multimap<K, V>,

Другие вопросы по тегам