Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can you modify an object without calling member functions?

Tags:

c++

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?

like image 429
R. Martinho Fernandes Avatar asked Jun 24 '11 10:06

R. Martinho Fernandes


2 Answers

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

like image 175
Cheers and hth. - Alf Avatar answered Oct 12 '22 00:10

Cheers and hth. - Alf


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.

like image 41
Lightness Races in Orbit Avatar answered Oct 12 '22 00:10

Lightness Races in Orbit