Mircea Ispas
Mircea Ispas

Reputation: 20780

Temporary objects type and life time

In the project I work I saw code very similary with next one:

std::string str = (std::string() += "some string") += "some other string";

For obvious reasons I can't reproduce the original code, but I can say it uses custom String and operator<< that has same behavior as operator+= for std::string.

I feel something is very wrong here, beside the creation/destruction of unnecessary temporary objects, but I don't know exactly what.

Are the temporary objects const? Is yes, how does this code compile(VS2010) because operator += mutates the object? Can you please explain what are the problems here?

Upvotes: 4

Views: 233

Answers (3)

Oberon
Oberon

Reputation: 3249

To make the lifetime point clearer, the standard says (12.2):

Temporary objects are destroyed as the last step in evaluating the full-expression (1.9) that (lexically) contains the point where they were created.

And (1.9):

A full-expression is an expression that is not a subexpression of another expression.

In this case this would (to my best knowledge) be the call to std::strings move constructor (which you technically do with the = initialization) with (std::string() += "some string") += "some other string". So, put simply, the lifetime of a temporary ends at the ;, which means you are safe here.

Upvotes: 1

UmNyobe
UmNyobe

Reputation: 22890

(std::string() += "some string") += "some other string";

can be broke into

temp1(std::string());
temp1 += "some string"
temp1 += "some other string";

The parenthesis define the precedence over both += operations. It does not define a scope, so temp1 is not destroyed by any means when this statement is executed.

On the other side the C++ Standard guaranties that both string literals have the lifetime of the program.

Thus, there is a minimal amount of temporary object on this code sample.

It can go for an arbitrary amount of literals

 std:string str =  ((((((std::string() += "a") += "b") += "c") += "d") += "e") += "f");

Upvotes: 2

ecatmur
ecatmur

Reputation: 157354

Temporary objects are not const; they are rvalues. That means they can bind to a const reference (C++03) or a (const or non-const) rvalue reference (C++11).

In addition, you can call non-const member functions on temporaries, including member operators; this is presumably what is happening in this case. Calling non-const member operators is dangerous as it can lead to leaking dangling references, but in this case you're OK as there are no references persisting outside the expression.

In C++11 we have rvalue references, so the expression can be rewritten more clearly and more safely as:

std::string str = std::string() + "some string" + "some other string";

The content of the string temporary is reused by the free operator+ via a move constructor; temporaries are left in a moved-from state.

Upvotes: 3

Related Questions