Eric Lilja posted:
I'm looking at an assignment where the students are expected to write a
class with a given purpose. According to the assignment, you should be
able to do this with instances of the class:
++instance_of_class;
The built-in preincrement operator yields an L-value.
It would be wise if the user-defined operator++(void) were also implemented
to yield an L-value, although the Standard does not require this.
instance_of_class++;
The built-in postincrement operator yields an R-value.
The user-defined operator++(int) can be implemented however you please, to
yield either an R-value or an L-value.
Personally, I never implement operator(int), I think it's too messy.
(++instance_of_class)++; // Isn't this invalid C++?
This is valid code for a built-in type, and it would make sense for it to
be valid code for the user-defined type also, although this is not required
by the Standard.
By "valid", I mean that it must compile.
but not:
++(instance_of_class++);
This will NOT compile for a built-in type, because it tries to increment an
R-value. Whether it works with an object of user-defined type depends upon
the way operator++(int) is written.
But doesn't the third thing the class should support,
(++instance_of_class)++;, violate the rule that says that a variable
may not be modified more than once between two sequence points or else
undefined behaviour is the result? I'm not looking to start a heated
discussion here, just want confirmation or denial from the gurus here
before I let the person behind the assignment know about his mistake
(if, in fact, he made one).
Nice catch!
The answer to the question is: Syntactic Sugar.
The expression actually becomes:
obj.operator++().operator++(5);
There is a sequence point between the function calls.
It could be argued, however, that:
(++obj)++
is bogus because:
(1) It's nonsensical.
(2) It goes against the way built-in types can be used (assuming that a
sequence point violation actually occurs -- although I'm not 100% sure if
one does).
--
Frederick Gotham