Почему 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>
или... Неважно, откуда это берутся, у вас просто есть один тип: "вид на несколько смежных int
s".
Правда, что 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>
,