Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

If temporaries are implicitly non-modifiable, how does this work?

I'm told that, in C++03, temporaries are implicitly non-modifiable.

However, the following compiles for me on GCC 4.3.4 (in C++03 mode):

cout << static_cast<stringstream&>(stringstream() << 3).str();

How is this compiling?

(I am not talking about the rules regarding temporaries binding to references.)

like image 971
Lightness Races in Orbit Avatar asked Jun 24 '11 10:06

Lightness Races in Orbit


1 Answers

I'm told that, in C++03, temporaries are implicitly non-modifiable.

That is not correct. Temporaries are created, among other circumstances, by evaluating rvalues, and there are both non-const rvalues and const rvalues. The value category of an expression and the constness of the object it denotes are mostly orthogonal 1. Observe:

      std::string foo();
const std::string bar();

Given the above function declarations, the expression foo() is a non-const rvalue whose evaluation creates a non-const temporary, and bar() is a const rvalue that creates a const temporary.

Note that you can call any member function on a non-const rvalue, allowing you to modify the object:

foo().append(" was created by foo")   // okay, modifying a non-const temporary
bar().append(" was created by bar")   // error, modifying a const temporary

Since operator= is a member function, you can even assign to non-const rvalues:

std::string("hello") = "world";

This should be enough evidence to convince you that temporaries are not implicitly const.

1: An exception are scalar rvalues such as 42. They are always non-const.

like image 199
fredoverflow Avatar answered Oct 25 '22 09:10

fredoverflow