4

So the C++ string function

string& erase ( size_t pos = 0, size_t n = npos )

returns *this. What does that mean? Why do I need it to return anything?

Example

string name = "jimmy";  
name.erase(0,1);

will erase j and become immy, but why do I need it to return anything at all?

dandan78
  • 13,328
  • 13
  • 64
  • 78
bluejimmy
  • 390
  • 6
  • 14

4 Answers4

9

For method chaining. For example, after you erase, you can call == on it to check something:

string name = "jimmy";
bool b = name.erase(0,1) == "immy";
Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
6

It is only for convenience, for example you can chain calls like this:

name.erase(0,1).erase(3,1);
Matzi
  • 13,770
  • 4
  • 33
  • 50
  • 2
    I think why would anyone do that? chaining-erase-with-erase? Not a practical example. – Nawaz Jan 02 '13 at 11:21
  • It makes perfect sense if you want to delete multiple parts of a string. However, you have to be careful with the indexes since the string changes after each erase. In the example given, it would delete the 5th character of the initial string, not the 4rd, since the first character is removed. – JvO Jan 02 '13 at 13:47
3

In your example you don't need it to return anything, because the expression:

name.erase(0,1)

is equivalent to:

((void)name.erase(0,1), name)

So for example you could write:

while(name.erase(0,1).size()) {
    std::cout << name << '\n';
}

or:

while((name.erase(0,1), name).size()) {
    std::cout << name << '\n';
}

or:

while(name.erase(0,1), name.size()) {
    std::cout << name << '\n';
} 

or:

while(true) {
    name.erase(0,1);
    if (!name.size()) break;
    std::cout << name << '\n';
}

The standard has decided to give you the choice, probably on the basis that it might as well use the return value for something rather than "waste" it.

Basically, it sometimes saves a little bit of code that repeats a variable name or takes a reference to an intermediate result.

Some people think that functions that modify the object they're called on should not return anything (the idea being to limit the use of functions with side-effects to one per statement). In C++ they just have to live with the fact that the designers of the standard library disagree.

Steve Jessop
  • 273,490
  • 39
  • 460
  • 699
  • I have seen people argue that the *waste* is returning something when it would not always be useful, because this would clog a CPU register uselessly etc... but personally I would favor never returning `void`. – Matthieu M. Jan 02 '13 at 13:22
  • @MatthieuM: well, I'd certainly dispute their claim that it's wasteful to return something when it's not *always* useful. If it's useful 999999 times out of a million then as a library designer you probably want to optimize for the common case. But anyway I agree, it might as well return it. People who don't like chaining mutations can just not chain them. IMO they don't need the language to prevent them chaining them. OTOH, if there were one function to mutate the object, and one with similar name to return a modified copy of the original then I probably *would* make the mutator return void. – Steve Jessop Jan 02 '13 at 13:59
  • Well, we could argue for the treshold; I don't have enough expertise to understand the cost of clogging a CPU register though :( – Matthieu M. Jan 02 '13 at 14:01
  • @MatthieuM: well, as a library designer you never really know for sure that the uncommon usage will always remain below a given threshold. Generally the official "common usage" is the *intended* usage, then someone surprises you with a clever idiom and you re-think your assumptions. Fortunately this is such a tiny performance issue that the official response can be "even if it is slower on some compiler when the return value is unused, it's worth it for the expressions it supports". `vector::erase` should get inlined anyway... – Steve Jessop Jan 02 '13 at 14:04
0

You can do things like this:

void process(std::string const &s) {}

process(name.erase(0,1)); //self-explanatory?

std::cout << name.erase(0,1) << std::endl; 

//etc

And things which the other answers has mentioned.

Nawaz
  • 353,942
  • 115
  • 666
  • 851