Question: ```
std::string Concatenate(const std::string& s1,
                        const std::string& s2,
                        const std::string& s3,
                        const std::string& s4,
                        const std::string& s5)
{
    return s1 + s2 + s3 + s4 + s5;
}

```

By default, `return s1 + s2 + s3 + s4 + s5;` may be equivalent to the following code:

```
auto t1 = s1 + s2; // Allocation 1
auto t2 = t1 + s3; // Allocation 2
auto t3 = t2 + s4; // Allocation 3

return t3 + s5; // Allocation 4

```

Is there an elegant way to reduce the allocation times to 1? I mean keeping `return s1 + s2 + s3 + s4 + s5;` not changed, but the efficiency is improved automatically. If it is possible, it can also avoid the programmer misusing `std::string::operator +`.

Does **ref-qualifier** member functions help?

Answer: 
The premise of the question that:

```
s1 + s2 + s3 + s4 + s5 + ... + sn

```

will require n allocations is incorrect.

Instead it will require O(Log(n)) allocations. The first `s1 + s1` will generate a temporary. Subsequently a temporary (rvalue) will be the left argument to all subsequent `+` operations. The standard specifies that when the lhs of a `string +` is an rvalue, that the implementation simply append to that temporary and move it out:

```
operator+(basic_string<charT,traits,Allocator>&& lhs,
          const basic_string<charT,traits,Allocator>& rhs);

Returns: std::move(lhs.append(rhs))

```

The standard also specifies that the capacity of the string will grow geometrically (a factor between 1.5 and 2 is common). So on every allocation, capacity will grow geometrically, and that capacity is propagated down the chain of `+` operations. More specifically, the original code:

```
s = s1 + s2 + s3 + s4 + s5 + ... + sn;

```

is *actually* equivalent to:

```
s = s1 + s2;
s += s3;
s += s4;
s += s5;
// ...
s += sn;

```

When geometric capacity growth is combined with the short string optimization, the value of "pre-reserving" the correct capacity is limited. I would only bother doing that if such code actually shows up as a hot spot in your performance testing.
After some thought, I think it might be worth at least considering a slightly different approach.

```
std::stringstream s;

s << s1 << s2 << s3 << s4 << s5;
return s.str();

```

Although it doesn't guarantee only a single allocation, we can expect a `stringstream` to be optimized for accumulating relatively large amounts of data, so chances are pretty good that (unless the input strings are huge) it will keep the number of allocations quite minimal.

At the same time, especially if the individual strings are reasonably small, it certainly avoids the situation we expect with something like `a + b + c + d` where (at least in C++03) we *expect* to see a number of temporary objects created and destroyed in the process of evaluating the expression. In fact, we can typically expect this to get pretty much the same kind of result we'd expect from something like expression templates, but with a lot less complexity.

There is something of a downside though: iostreams (in general) have enough baggage such a associated locales that especially if the strings are small, there could be more overhead in creating the stream than we save in individual allocations.

With a current compiler/library, I'd expect the overhead of creating a stream to make this slower. With an older implementation, I'd have to test to have any certainty at all (and I don't have an old enough compiler handy to do so).