0

In the language I was first introduced to, there was a function repeat(), that took a string, and repeated it n times. For example, repeat ("hi", 3) gives a result of "hihihi".

I did have quite a few times that I used this function, but to my dismay, I've never found something similar in C++. Yes, I can easily make my own, or make it easier to use, but I'm kind of surprised that it isn't included already.

One place it would fit in really well is in std::string:

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

That would allow for syntax such as:

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

Now that in itself isn't all too great yet, but it could be better, which brings me to my other part: literals.

Any time we use the string operators, such as operator+, we have to make sure one argument is actually a string. Why didn't they just define a literal for it, like ""s? Literal suffixes not beginning with an underscore are reserved for the implementation, so this shouldn't conflict seeing as how this could have been added before anyone actually started making their own.

Coming back to the repeat example, the syntax would simply be:

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

This would produce:

123123123456

While at it, one for characters could be included as well, to satisfy cout << '1's + '2's;

Why weren't these two features included? They definitely have a clear meaning, and make coding easier, while still using the standard libraries.

chris
  • 60,560
  • 13
  • 143
  • 205
  • 3
    Keep I mind c++ is not perl... – Cole Tobin May 14 '12 at 21:24
  • It may not be, nor is that what I was referencing, but they've constantly been making C++ more user friendly. Just look at `auto`. Did these never occur to them? – chris May 14 '12 at 21:26
  • @fontanini, besides `s` being a reserved suffix, I'd see it a lot more convenient if it was already there each time I wanted to use it. – chris May 14 '12 at 21:28
  • `typedef std::string s; cout << s("123") * 3;` – Mark Ransom May 14 '12 at 21:39
  • With C++11 you have user-defined literals, so you could write your own suffix if you wanted to. – Stephen Newell May 14 '12 at 21:42
  • @MarkRansom, yes, I could also do `"123"_s * 3` within limitations, but you'd still have to define these every time you want to use them, or include a header that does. – chris May 14 '12 at 21:43
  • With C++11 user defined literals it's entirely possible that a future library update _will_ introduce std::string literals. It will be part of the library rather than the language though. If you want string 'multiplication' though you can propose it yourself (and you're more likely to be successful if you propose it in the form of a constructor `string(size_type n,const string &s, const Allocator a = Allocator())` and `string(size_type n,const char *s, const Allocator a = Allocator())`) – bames53 May 14 '12 at 21:50
  • @chris, what's wrong with header files? I've always been at my most productive when I have a library of building blocks that I can rely on. – Mark Ransom May 14 '12 at 21:56
  • @MarkRansom, I have nothing against them, but I'd have to decide how to group things so it's not everything in one, or one per file. It is a worthwhile thing to use though. – chris May 14 '12 at 22:03
  • 1
    I really fail to understand a realistic use-case for this that [constructor #2](http://en.cppreference.com/w/cpp/string/basic_string/basic_string) doesn't already cover. Really? In _real_ code? – ildjarn May 14 '12 at 22:05
  • @chris: You would have to include header files just in the same way that you need to include a header file to use `std::string`... – David Rodríguez - dribeas May 14 '12 at 22:12
  • @ildjarn: That doesn't make sense. Constructor #2 takes a *character* to repeat, not a string. – Nicol Bolas May 14 '12 at 23:08
  • @Nicol : Is that confusing to you somehow? When have you needed to repeat a _string_ in real code? – ildjarn May 15 '12 at 02:48
  • @ildjarn: Obviously he has; otherwise this thread wouldn't exist. – Nicol Bolas May 15 '12 at 03:36

2 Answers2

4

Well, as for the multiplication, it's not really in C++'s philosophy: languages like Ruby come "batteries included" and with the "principle of least surprise". They are intended to have lots of these little niceties as an above-and-beyond-the-minimum feature. C++ is a system level language which is intended to be "closer to the metal", which is abundantly clear in that a string isn't even a core data type of the language, but a library-provided addon. Even FORTRAN has a native string type, so you can see how low-level C++ is positioned to be. This is intentional: what if you're programming an embedded chip with 1K storage and have no use for strings? Just don't include 'em.

Anyway, it's not 100% clear what the multiplication operator is supposed to do. In other words, in the core language and libraries of C++, no feature gets in unless it seems that almost everyone would agree on the proposed functionality. It's got to be really universal.

I for one might think that "123" * 3 could give "369" - multiply any digits by 3. I further propose that this interpretation is "sane" enough to keep your repeat operator interpretation from being the only unambiguous interpretation.

The literal notation is far easier and more clear to answer: std::string is a part of the standard library, which is one level of abstraction above the language syntax itself. In other words, the literal notation would bust through the level of abstraction that separates "language features" and "the library that you can expect to be bundled with your compiler".

Matt
  • 10,434
  • 1
  • 36
  • 45
  • I'm just curious, what else would the operator do? – chris May 14 '12 at 21:29
  • In particular, a syntax for `std::string` literals would require the compiler be able to construct a valid `std::string`, so it would have to know the details of the implementation thereof. In theory this would get in the way if you wanted to swap a different implementation of the standard library in. In practice no one ever really does this, but a great many design decisions in C++ are informed by theoretical rather than pragmatic considerations. – Russell Borogove May 14 '12 at 21:31
  • About that use, I see what you mean. I never thought of that one. I guess it could make sense given the context. @RussellBorogove, I see your point. – chris May 14 '12 at 21:36
  • After using more modern languages with built-in string datatypes, the history of C++'s evolution seems like an attempt to add all the features you need to implement the ultimate all-things-to-all-people string datatype. – Russell Borogove May 14 '12 at 21:41
  • @Russell : And yet this feature would be missing. Go figure. (I have no idea what you're on about, but it smells like FUD.) – ildjarn May 14 '12 at 22:18
  • That's correct, you have no idea what I'm on about. I said 'to implement', not 'to use in a convenient manner'. – Russell Borogove May 14 '12 at 22:54
  • 1
    @Russell : I'd wager _you_ have no idea what you're on about. Every reasonable complaint about `std::string` that I've seen is that it's lacking in functionality, not surplus. – ildjarn May 15 '12 at 02:50
  • I'm not talking about `std::string`; I'm talking about language features that allow shortcomings of `std::string` to be addressed with "you can just make your own string class that does that." – Russell Borogove May 15 '12 at 17:18
  • @ildjarn: just for variety, you could read Sutter's 'Monoliths "Unstrung"', which is a reasonable complaint that the `std::string` class has too much functionality (it concludes: 'Guideline: Prefer "one class (or function), one responsibility."'). *But*, if you consider free functions that take one or more `string` parameters as being "part of" `std::string`, then you'd still conclude that those things should be functionality of `std::string`, and should be joined by `split` etc. In those terms you'd have to say that the guideline "one class, one responsibility" is utterly wrong-headed. – Steve Jessop Jul 10 '12 at 21:53
1

std::string.append(numtimes, char to repeat); There. It does. Now, that works for character literals, as for doing that with strings there is no way to do that declaratively. Also to note, the std::string class isn't a language type, a string litteral in c++ is const char *. A pointer. Which Arrays decay into pointers, and that's how the std::string class treats what it contains , an array of characters ie char, or wchar_t for std::wstring. there templated on those types.

johnathan
  • 2,315
  • 13
  • 20
  • It's still a real step down from `s += 3 * "str"s;` in my opinion. The former may be crystal clear, but the latter flows out pretty well. – chris May 14 '12 at 21:30
  • 1
    one cant multiply strings, what that means in other languages is beyond me, AFIK you cant even do that in c#, or java. – johnathan May 14 '12 at 21:32
  • and you have to remember, C++ is not an interpreted language, and it's not managed either. There's a lot about the syntax of the language that allows it to be as close to the metal as possible, and yet still retain very fast and strong abstractions away from the machine, i mean yes, you can twiddle bits if you Need to, but in most cases that's simply not needed, and often times i see code that is overly complex when good c++ constructs could be used. To note, you could probably achieve what you wanting to do with a simple expression template. – johnathan May 14 '12 at 21:35
  • @chris : What real software in existence would have occasion to do something like that? Is it convenient? Sure. Is it needed? Absolutely __not__. – ildjarn May 14 '12 at 22:10