Почему std::string не определяет умножение или литералы?

В языке, с которым я впервые познакомился, была функция repeat(), которая брала строку и повторяла ее n раза. Например, repeat ("hi", 3) дает результат "hihihi".

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

Одно место, куда он действительно хорошо вписался бы, это std::string:

std::string operator* (const std::string &text, int repeatCount);
std::string operator* (int repeatCount, const std::string &text);

Это позволит использовать такой синтаксис, как:

cout << "Repeating \"Hi\" three times gives us \"" << std::string("Hi") * 3 << "\"."

Это само по себе еще не слишком хорошо, но могло бы быть и лучше, что подводит меня к другой моей части: литералам.

Каждый раз, когда мы используем строковые операторы, такие как operator+, мы должны убедиться, что один из аргументов действительно является строкой. Почему они просто не определили для него литерал, например ""s? Буквенные суффиксы, не начинающиеся с подчеркивания, зарезервированы для реализации, поэтому это не должно противоречить тому, как это можно было добавить до того, как кто-то действительно начал создавать свои собственные.

Возвращаясь к повторному примеру, синтаксис будет таким:

cout << "123"s * 3 + "456"s;

Это произведет:

123123123456

При этом можно также включить один для персонажей, чтобы удовлетворить cout << '1's + '2's;

Почему не были включены эти две функции? Они определенно имеют ясное значение и упрощают кодирование, при этом используя стандартные библиотеки.


person chris    schedule 14.05.2012    source источник
comment
Имейте в виду, что C++ не perl...   -  person Cole Johnson    schedule 15.05.2012
comment
Возможно, это не так, и это не то, на что я ссылался, но они постоянно делают C++ более удобным для пользователя. Просто посмотрите на auto. Неужели это никогда не приходило им в голову?   -  person chris    schedule 15.05.2012
comment
@fontanini, помимо того, что s является зарезервированным суффиксом, мне было бы намного удобнее, если бы он уже был там каждый раз, когда я хотел его использовать.   -  person chris    schedule 15.05.2012
comment
В С++ 11 у вас есть определяемые пользователем литералы, поэтому вы можете написать свой собственный суффикс, если хотите.   -  person Stephen Newell    schedule 15.05.2012
comment
@MarkRansom, да, я также мог бы сделать "123"_s * 3 с ограничениями, но вам все равно придется определять их каждый раз, когда вы хотите их использовать, или включать заголовок, который это делает.   -  person chris    schedule 15.05.2012
comment
С определяемыми пользователем литералами C++11 вполне возможно, что в будущем обновлении библиотеки будут введены литералы std::string. Однако это будет часть библиотеки, а не языка. Если вам нужно «умножение» строк, вы можете предложить его самостоятельно (и у вас больше шансов на успех, если вы предложите его в форме конструктора string(size_type n,const string &s, const Allocator a = Allocator()) и string(size_type n,const char *s, const Allocator a = Allocator()))   -  person bames53    schedule 15.05.2012
comment
@chris, что не так с заголовочными файлами? Я всегда был наиболее продуктивным, когда у меня есть библиотека строительных блоков, на которые я могу положиться.   -  person Mark Ransom    schedule 15.05.2012
comment
@MarkRansom, я ничего не имею против них, но мне нужно решить, как сгруппировать вещи, чтобы не было всего в одном или по одному в файле. Тем не менее, это стоящая вещь для использования.   -  person chris    schedule 15.05.2012
comment
Я действительно не понимаю реалистичного варианта использования этого конструктора №2 уже не покрывает. Действительно? В реальном коде?   -  person ildjarn    schedule 15.05.2012
comment
@chris: вам нужно будет включить заголовочные файлы точно так же, как вам нужно включить заголовочный файл, чтобы использовать std::string...   -  person David Rodríguez - dribeas    schedule 15.05.2012
comment
@ildjarn: Это не имеет смысла. Конструктор №2 принимает для повторения символ, а не строку.   -  person Nicol Bolas    schedule 15.05.2012
comment
@Nicol: Вас это как-то смущает? Когда вам нужно было повторить строку в реальном коде?   -  person ildjarn    schedule 15.05.2012
comment
@ildjarn: Очевидно, что да; иначе этой ветки не было бы.   -  person Nicol Bolas    schedule 15.05.2012


Ответы (2)


Ну, что касается умножения, то это не совсем в философии C++: такие языки, как Ruby, поставляются «с включенными батареями» и с «принципом наименьшего удивления». Они предназначены для того, чтобы иметь множество этих маленьких тонкостей в качестве сверхминимальной функции. C ++ - это язык системного уровня, который должен быть «ближе к металлу», что совершенно очевидно, поскольку string является даже не основным типом данных языка, а надстройкой, предоставляемой библиотекой. Даже FORTRAN имеет встроенный строковый тип, так что вы можете видеть, насколько низкоуровневым является C++. Это сделано намеренно: что, если вы программируете встроенный чип с памятью 1 КБ и не используете строки? Просто не включайте их.

В любом случае, не на 100% ясно, что должен делать оператор умножения. Другими словами, в основном языке и библиотеках C++ ни одна функция не используется, если не кажется, что почти все согласны с предлагаемой функциональностью. Он должен быть действительно универсальным.

Я, например, мог бы подумать, что "123" * 3 может дать "369" - умножьте любые цифры на 3. Я также предлагаю, чтобы эта интерпретация была достаточно "разумной", чтобы ваша интерпретация повторного оператора не была единственной однозначной интерпретацией.

Буквальное обозначение гораздо проще и понятнее для ответа: std::string является частью стандартной библиотеки, которая находится на один уровень абстракции выше синтаксиса самого языка. Другими словами, буквальное обозначение прервет уровень абстракции, разделяющий «функции языка» и «библиотеку, которую вы можете ожидать в комплекте с вашим компилятором».

person Matt    schedule 14.05.2012
comment
Мне просто любопытно, что еще оператор мог сделать? - person chris; 15.05.2012
comment
В частности, синтаксис для литералов std::string потребует от компилятора возможности построить действительный std::string, поэтому он должен знать подробности его реализации. Теоретически это могло бы помешать, если бы вы захотели заменить другую реализацию стандартной библиотеки. На практике никто никогда этого не делает, но очень многие проектные решения в C++ основаны на теоретических, а не прагматических соображениях. - person Russell Borogove; 15.05.2012
comment
Что касается этого использования, я понимаю, что вы имеете в виду. Я никогда не думал об этом. Я думаю, это может иметь смысл, учитывая контекст. @RussellBorogove, я понимаю твою точку зрения. - person chris; 15.05.2012
comment
После использования более современных языков со встроенными строковыми типами данных история развития C++ кажется попыткой добавить все функции, необходимые для реализации универсального строкового типа данных «все для всех». - person Russell Borogove; 15.05.2012
comment
@Russell: И все же эта функция будет отсутствовать. Иди разберись. (Я понятия не имею, о чем вы, но это пахнет FUD.) - person ildjarn; 15.05.2012
comment
Правильно, вы понятия не имеете, о чем я. Я сказал «реализовать», а не «использовать удобным способом». - person Russell Borogove; 15.05.2012
comment
@Рассел: Держу пари, ты понятия не имеешь, о чем говоришь. Все разумные жалобы на std::string, которые я видел, заключались в том, что ему не хватает функциональности, а не избыток. - person ildjarn; 15.05.2012
comment
Я не говорю о std::string; Я говорю о языковых функциях, которые позволяют устранить недостатки std::string, и вы можете просто создать свой собственный строковый класс, который делает это. - person Russell Borogove; 15.05.2012
comment
@ildjarn: просто для разнообразия вы можете прочитать «Monoliths Unstrung» Саттера, который является разумной жалобой на то, что класс std::string имеет слишком много функциональных возможностей (в нем делается вывод: «Рекомендация: предпочитайте один класс (или функцию), одну ответственность»). Но если вы считаете бесплатные функции, которые принимают один или несколько параметров string частью std::string, то вы все равно придете к выводу, что эти вещи должны быть функциями std::string и к ним должны присоединяться split и т. д. В этих терминах вы должны были бы сказать, что руководство «один класс, одна ответственность» совершенно ошибочно. - person Steve Jessop; 11.07.2012

std::string.append(numtimes, char для повторения); Там. Оно делает. Теперь это работает для символьных литералов, а для строк это невозможно сделать декларативно. Также следует отметить, что класс std::string не является языковым типом, строковый литерал в С++ — это const char *. Указатель. Какие массивы распадаются на указатели, и именно так класс std::string обрабатывает то, что он содержит, массив символов, например char, или wchar_t для std::wstring. там шаблоны по этим типам.

person johnathan    schedule 14.05.2012
comment
На мой взгляд, это все еще настоящий шаг вперед по сравнению с s += 3 * "str"s;. Первый может быть кристально чистым, но второй вытекает довольно хорошо. - person chris; 15.05.2012
comment
нельзя умножать строки, что это значит на других языках, мне не понятно, AFIK, вы даже не можете сделать это в С# или java. - person johnathan; 15.05.2012
comment
и вы должны помнить, что C++ не является интерпретируемым языком, и он также не является управляемым. В синтаксисе языка много всего, что позволяет ему быть как можно ближе к металлу, но при этом сохранять очень быстрые и сильные абстракции вдали от машины, я имею в виду, что да, вы можете крутить биты, если вам нужно, но в большинстве случаев это просто не нужно, и часто я вижу слишком сложный код, когда можно использовать хорошие конструкции С++. Следует отметить, что вы, вероятно, могли бы добиться того, что хотите сделать, с помощью простого шаблона выражения. - person johnathan; 15.05.2012
comment
@chris: Какое реально существующее программное обеспечение могло бы сделать что-то подобное? Это удобно? Конечно. Это необходимо? Абсолютно нет. - person ildjarn; 15.05.2012