Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Temporary objects type and life time

Tags:

c++

c++11

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?

like image 981
Mircea Ispas Avatar asked Oct 14 '25 08:10

Mircea Ispas


2 Answers

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.

like image 117
ecatmur Avatar answered Oct 17 '25 17:10

ecatmur


(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");
like image 22
UmNyobe Avatar answered Oct 17 '25 18:10

UmNyobe