Почему у std::string_view нет методов assign() и clear()?

Реализация этих методов кажется мне простой, и они сделают использование std::string и std::string_view более взаимозаменяемым. В конце концов, у std::string_view есть конструкторы, которые оставляют объект в том же состоянии, что и эти методы. Можно было бы обойти отсутствующие методы следующим образом:

std::string s {"abcd"};
std::string_view v {s.c_str()};
std::cout << "ctor:   " << v << std::endl; // "abcd"
v = {s.c_str() + 1, 2};
std::cout << "assign: " << v << std::endl; // "bc"
v = {nullptr}; // or even v = {};
std::cout << "clear:  " << v << std::endl; // ""

Итак, каковы причины того, что эти два очевидных метода не включены в стандарт?

ОБНОВЛЕНИЕ: кажется, что один общий вопрос в ваших комментариях звучит так: «В чем смысл?», поэтому я дам вам некоторый контекст. Я разбираю большую строку, в результате чего получается структура подстрок. Эта результирующая структура является естественным кандидатом для строковых представлений, поэтому мне не нужно копировать все эти строки, которые даже перекрываются. Частью результата являются сопоставления со строковыми представлениями, поэтому мне может понадобиться сконструировать их пустыми, когда я получу ключ, и заполнить их позже, когда я получу значение. При синтаксическом анализе мне нужно отслеживать промежуточные строки, что включает их обновление и сброс. Теперь их можно было заменить строковыми представлениями, и именно так я и поступил с этими отсутствующими функциями. Конечно, я мог бы продолжать использовать строки или заменить их на старые добрые пары ptr-ptr или ptr-size, но именно для этого и предназначен std::string_view, верно?


person Simpleton    schedule 24.01.2019    source источник
comment
Чтобы было ясно: вы ожидаете, что они заставят объект смотреть на другую строку (фактически не изменяя текущую просматриваемую строку)?   -  person Max Langhof    schedule 24.01.2019
comment
Да, просто изменить представление, а не базовую строку.   -  person Simpleton    schedule 24.01.2019
comment
Это семантически отличается от соответствующих методов std::string (вероятно, именно по этой причине вы ищете). Точно так же изменение указателя на nullptr отличается от удаления объекта, на который он указывает.   -  person Max Langhof    schedule 24.01.2019
comment
Afaik, основная цель string_view - заменить const string& в параметрах функции. Хороший вопрос, в чем смысл string_view::clear и string_view::assign.   -  person Yuriy Pozniak    schedule 24.01.2019
comment
@MaxLanghof Думаю, я понимаю, о чем вы говорите, но я не согласен с семантической разницей. Вы очищаете строку и очищаете представление, после чего оба пусты. Та же семантика. На самом деле не имеет значения, происходит ли какое-то освобождение памяти или что-то еще, что происходит под капотом. В противном случае std::vector<int>::clear() будет семантически отличаться от std::vector<int*>::clear(), не так ли?   -  person Simpleton    schedule 24.01.2019
comment
@Simpleton Нет, аналогия с вектором не работает. Вы удаляете (и освобождаете) все элементы. И int, и int* легко освобождаются, семантической разницы нет. Кстати, я согласен с вами, что есть интерпретации assign и clear, в которых нет ярко выраженной семантической разницы. Но вы должны согласиться с тем, что может возникнуть путаница, если clear также очищает саму просматриваемую строку - в конце концов, std::string делает это.   -  person Max Langhof    schedule 24.01.2019
comment
@MaxLanghof Моя точка зрения заключалась в том, что вектору принадлежит указатель, который он освобождает (точно так же, как значения int), но не указатель, который он не освобождает. Мы с тобой и все остальные это знаем. То же самое с string_view, на мой взгляд, указатель никогда не будет освобожден при очистке(). Почему string_view это делает, это просто представление существующего объекта, а не интеллектуальный указатель. Тем не менее, люди, кажется, согласны с вами и ожидают, что он будет работать с базовой строкой. Во всяком случае, ваша точка зрения ясна, хотя я не согласен. Спасибо за ваш вклад, но давайте прекратим обсуждение семантики.   -  person Simpleton    schedule 24.01.2019


Ответы (3)


На самом деле это будет только предположение, но общий консенсус, похоже, заключается в том, что эти операции будут довольно неясными.

Лично я думаю, что «очищение представления» имеет смысл (и давайте также не будем забывать, что remove_prefix и remove_suffix существуют! Хотя см. ниже...), но я также согласен с тем, что есть другие интерпретации, которые могут быть распространены, но не имеют смысла. . Напомним, что string_view предназначен для дополнения const std::string&, а не std::string, и ни одна из названных вами функций не является частью постоянного интерфейса std::string.

Честно говоря, тот факт, что нам вообще нужна эта беседа, сам по себе, вероятно, является веской причиной, чтобы вообще не иметь этой функции.

Из окончательного предложения по string_view , следующий отрывок не касается конкретно assign или clear, но действует как соответствующее мнение [lol] в умах комитета по этому вопросу:

s/remove_prefix/pop_front/, etc.

В Kona 2012 я предложил класс range<> с pop_front и т. д. членами, которые корректировали границы диапазона. Обсуждение показало, что членам комитета неудобно использовать те же имена для упрощенных операций с диапазонами, что и для операций с контейнерами. Существующая практика не согласуется с названием для этой операции, поэтому я оставил имя, используемое Google StringPiece.

Это предложение действительно включало clear(), который был бесцеремонно исключен из реестра в более позднем, изолированном, лишенном обоснования предложении.

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

Поскольку мы можем достаточно легко присвоить новое string_view, в том числе и пустое, вся проблема решается, просто не утруждая себя ее решением.

person Lightness Races in Orbit    schedule 24.01.2019
comment
Это хорошая информация о remove_prefix и remove_suffix. В этом предложении также рассматривается, почему он существует, даже если он не находится в строке (предположительно полезность), но не почему, если он добавлен в представление, почему бы также не добавить его в строку. - person Jeff Garrett; 24.01.2019
comment
вся проблема решается тем, что вы просто не удосужились ее решить. Ну, мне просто было любопытно, почему не включены эти функции. Я надеялся, что кто-то вмешается с соответствующим отрывком из стандарта вместо того, чтобы люди высказывали свое (для меня неоправданное) недовольство этими гипотетическими функциями. А вот и что там написано? Они опустили их, потому что некоторым членам комитета это не понравилось. Ну ладно... Видя обсуждение здесь, это, вероятно, было оправдано... Отмечено как отвеченное. - person Simpleton; 24.01.2019
comment
@Simpleton Чтобы уточнить, именно комитет решил проблему, не решая ее, просто не добавляя эти функции. Это был справедливый вопрос; Я просто не думаю, что мы можем сделать лучше, чем выше. Конечно, в нормативном или ненормативном стандартном тексте нет никакого обоснования по этому поводу. - person Lightness Races in Orbit; 24.01.2019
comment
@LightnessRacesinOrbit, это окончательное предложение? Кажется, это ясно? - person Jeff Garrett; 24.01.2019
comment
@JeffGarrett О, чувак, так оно и есть ... (а) кто-то солгал мне, и (б) сюжет сгущается. Мне придется пересмотреть это утром. Хорошее место! - person Lightness Races in Orbit; 25.01.2019
comment
Но затем: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4288.html К сожалению, без объяснений... - person Simpleton; 25.01.2019
comment
@Простак, лол. - person Lightness Races in Orbit; 25.01.2019

Интерфейс std::string имеет плохую репутацию из-за его несовершенного API, поэтому std::string_view очень вряд ли получит столько же методов, сколько std::string, только потому, что это удобно или делает два типа более взаимозаменяемыми.

Но что более важно, эти типы не должны быть взаимозаменяемыми. Что означает «очищение» представления контейнера символов? Поскольку clear() присутствует во всех контейнерах STL и делает что-то значимое, наличие std::string_view::clear() было бы довольно запутанным.

Кроме того, просмотр некоторых данных предназначен для временного использования, например. параметр функции только для чтения. Почему вы хотите назначить его в любом случае? Вот пример сигнатуры функции, использующей std::string_view:

// Called e.g. with "x86_64-Darwin-16.7.0"
std::string_view extractOSName(std::string_view configStr)
{
    // Parse input, return a new view. Lifetime/ownership managed by caller.
    // No need to re-assign anything, let alone "clearing" them.
}
person lubgr    schedule 24.01.2019
comment
Я согласен с тем, что std::string API полностью раздут, но функции assign() и clear() практически стандартны во всех контейнерах. И std::string_view действует как контейнер в том смысле, что не имеет значения, смотрите ли вы на std::string_view или std::string const &. Вот что я имел в виду под взаимозаменяемостью. Но я не понимаю, что может смущать в std::string_view::clear(). Что еще он мог сделать, кроме очистки представления, чтобы потом оно было пустым? Никто не ожидал, что он на самом деле удалит базовую строку, верно? - person Simpleton; 24.01.2019
comment
Вы говорите, что не должно иметь значения, смотрите ли вы на std::string_view или std::string const &, но не означает ли это, что assign вообще не имеет смысла, потому что std::string const& нельзя изменить? По теме clear: я думаю, что представления должны быть недолговечными объектами, в первую очередь для параметров функций. Переустановка объекта, который они просматривают, может быть просто не тем сценарием, для которого они были разработаны? Но это не более чем предположение. - person lubgr; 24.01.2019
comment
Я предполагаю, что нужно различать создание строкового представления и его использование. Строительство может быть не таким простым, как вызов одного конструктора, см. контекст, который я предоставил в своем вопросе. Есть также функции std::string_view::remove_prefix/suffix(), которые не являются константами. Но я думаю, что использование std::string_view const & должно быть почти неотличимо от использования std::string const &. - person Simpleton; 24.01.2019

Реализация этих методов кажется мне простой, и они сделают использование std::string и std::string_view более взаимозаменяемым.

std::string_view не предназначен для замены std::string. Он предназначен для замены const std::string&. assign и clear не являются функциями-членами const std::string&, которые вы можете вызывать.

person Jeff Garrett    schedule 24.01.2019
comment
Хороший вопрос, но ни remove_prefix, ни remove_suffix - person Lightness Races in Orbit; 24.01.2019