First, there's a difference between "modifying a temporary" and "modifying an object through an rvalue". I'll consider the latter, since the former is not really useful to discuss [1].
I found the following at 3.10/10
(3.10/5
in C++11):
An lvalue for an object is necessary
in order to modify the object except
that an rvalue of class type can also
be used to modify its referent under
certain circumstances. [Example: a
member function called for an object
(9.3) can modify the object. ]
So, rvalues are not const
per-se but they are non-modifiable under all but some certain circumstances.
However, that a member function call can modify an rvalue would seem to indicate to me that the vast majority of cases for modifying an object through an rvalue are satisfied.
In particular, the assertion (in the original question I linked to) that (obj1+obj2).show()
is not valid for non-const
show()
[ugh, why?!] was false.
So, the answer is (changing the question wording slightly for the conclusion) that rvalues, as accessed through member functions, are not inherently non-modifiable.
[1] - Notably, if you can obtain an lvalue to the temporary from the original rvalue, you can do whatever you like with it:
#include <cstring>
struct standard_layout {
standard_layout();
int i;
};
standard_layout* global;
standard_layout::standard_layout()
{
global = this;
}
void modifying_an_object_through_lvalue(standard_layout&&)
{
// Modifying through an *lvalue* here!
std::memset(global, 0, sizeof(standard_layout));
}
int main()
{
// we pass a temporary, but we only modify it through
// an lvalue, which is fine
modifying_an_object_through_lvalue(standard_layout{});
}
(Thanks to Luc Danton for the code!)
const
". And as it turns out, to a point, this is exactly what they are. – Algiastd::vector<int>().resize( 100 );
is perfectly valid, creates a temporary and modifies it (without the need for a cast as in your example). – Brouhaha.str()
, becauseop+
returnsostream
. It's a bit of a red herring here as it has nothing to do with the question specifically. – Algiastatic_cast
and would not be able to remove const-ness. – Danettedaneyoperator<<(int)
is a member function ofbasic_ostream
anyway, so whatever special rule you think applies tovector::resize
, it would in any case also apply to your code. The cast is just a downcast back tostringstream
, sinceoperator<<
returnsbasic_ostream&
. – Schallesconst
reference to a temporary, casting away const and modifying it, is legal, just make sure the reference doesn't outlive the temporary. – Schalles