Почему std :: span это указатель + размер, а не два итератора - PullRequest
5 голосов
/ 28 июня 2019

Похоже, что std::span в C ++ 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 Ответ

8 голосов
/ 28 июня 2019

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

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

Это правда, что 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>.

...