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: 
You can use code like:

```
std::string(s1) + s2 + s3 + s4 + s5 + s6 + ....

```

This will allocates a single unnamed temporary (copy of the first string), and then append each of the other strings to it. A smart optimizer could optimize this into the same code as the reserve+append code others have posted, as all these functions are generally inlineable.

This works by using the move-enhanced version of operator+, which is defined as (roughly)

```
std::string operator+(std::string &&lhs, const std::string &rhs) {
    return std::move(lhs.append(rhs));
}

```

combined with RVO, it means that no additional `string` objects need to be created or destroyed.
How about this:

```
std::string Concatenate(const std::string& s1,
                        const std::string& s2,
                        const std::string& s3,
                        const std::string& s4,
                        const std::string& s5)
{
    std::string ret;
    ret.reserve(s1.length() + s2.length() + s3.length() + s4.length() + s5.length());
    ret.append(s1.c_str());
    ret.append(s2.c_str());
    ret.append(s3.c_str());
    ret.append(s4.c_str());
    ret.append(s5.c_str());
    return ret;
}

```

There are two allocations, one really small to construct `std::string` another reserves memory for data.