c++temporaries

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.)


Solution

  • 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.