Почему string_view вместо обобщенного контейнера_view & lt; T & gt ;?

Я нашел string_view из нового стандарта C ++ 17 немного избыточным.

У нас есть довольно подробная коллекция простых механизмов для передача данных вызываемой стороне, без больших накладных расходов, и теперь есть один другой, который также специфичен только для одного типа контейнера.

Я не понимаю, зачем предоставлять этот механизм только для строк, а не какой-то более обобщенный тип для других контейнеров. Один разумный ответ состоит в том, что у нас уже были такие решения. Например в C ++ 17 и выше представление string_view объясняется как observer_ptr<T> (or T*) for string,

Пожалуйста, сформулируйте аргументы против более общего container_view, в отличие от string_view, введенного C ++ 17.

15

Решение

Обобщенный container_view более правильно называется спектр. У нас есть TS в пути, полностью посвященный концепциям ассортимента.

Теперь у нас есть string_view как отдельный тип, потому что он имеет специализированный, специфичный для строки интерфейс, чтобы соответствовать basic_stringСтроковый интерфейс. Или, по крайней мере, чтобы соответствовать постоянным / нераспределенным интерфейсам.

Обратите внимание, что container_view или что бы вы ни назвали, оно не сможет стереть свою связь с контейнером, который его сгенерировал. Или, по крайней мере, не без дополнительных затрат на стирание типа при каждом доступе / операции.

В отличие от string_view основывается на const char*с и целые числа. Этому классу все равно, откуда взялась строка; он дает представление о непрерывном множестве символов, независимо от того, кому он принадлежит. Он может сделать это, потому что знает, что источник является непрерывным массивом, и поэтому использует указатели в качестве ядра своего итератора.

Вы не можете сделать это для произвольных контейнеров. Ваш container_view<vector> будет иметь разные итераторы из container_view<list> или что угодно. Было бы должен. Что означает, что если вы возьмете container_view в качестве параметра функции вы должны либо выбрать конкретный контейнер для использования (вынуждая пользователя предоставлять именно этот тип контейнера), либо сделать свою функцию шаблоном, либо использовать диапазон итераторов со стертыми типами (таким образом, медленнее).

Также есть предложения после C ++ 17 для типов GSL span а также mdspan, Первый представляет изменяемый «вид» смежный массив. Последний представляет модифицируемое «представление» непрерывного массива, который вы рассматриваете как многомерный.

13

Другие решения

string_view предлагает больше, чем простой указатель на строку.
Вы должны смотреть на это как на нечто большее, чем просто не принадлежащий указатель: если это все, string_view не может позволить вам «разрезать» части строки и применить к ней операции (все еще являясь представлением; таким образом, не требуя затрат на копирование):

char *s = "welcome to stackoverflow";
auto s = std::string_view{s + 8, 2}; // a view on "to"// you can then apply many operations on this view, that wouldn't make sense more on your general non_owning<T>:
s.remove_prefix(std::min(s.find_first_not_of(" "), s.size()));
// it also "inherits" (copies the API) a lot directly from std::basic_string
auto view2 = s.substr(3, 4); // a generic non-owning ptr would copy here, instead of giving you a new view
4

По вопросам рекламы [email protected]