At 3.10/10, the standard says:
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 non-modifiable except under certain circumstances. We're told that calling a member function is one of those exceptions. This gives the idea that there are ways of modifying objects other than calling a member function. I can't think of a way.
How can one modify an object without calling a member function?
How can one modify an object [that's specified by an rvalue expression] without calling a member function?
I know of only one way to do that, namely to bind the object to a reference to const
, and then cast away the const
-ness.
E.g.
template< class Type >
Type& tempRef( Type const& o ) { return const_cast< Type& >( o ); }
struct S { int x; };
int main()
{ tempRef( S() ).x = 3; }
This is because a temporary object is not const
itself unless it is of const
type, so the example above does not cast away original const
-ness (which would be UB).
EDIT, added: Luc Danton’s answer showed another (non-general) way, namely where the temporary's construction stores some reference or pointer to the object in some accessible location.
Cheers & hth.,
This seems to be accepted:
struct T {
int x;
};
int main() {
T().x = 3;
}
I am slightly surprised that this works, because IIRC the LHS of op=
must be an lvalue, yet the following implies that even T().x
is an rvalue:
struct T {
int x;
};
void f(int& x) {
x = 3;
}
int main() {
f(T().x);
}
Edit: As of 4.6, GCC does warn about T().x = 3
: error: using temporary as lvalue
.
I can't think of any other way to modify a class object other than through data member access or member function calls. So, I'm going to say... you can't.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With