On Fri, 01 Mar 2013 20:37:26 -0500, Era Scarecrow <[email protected]>
wrote:
On Saturday, 2 March 2013 at 01:15:20 UTC, Steven Schveighoffer wrote:
void main()
{
auto t = foo;
t++; // ok
foo++; // Error: foo() is not an lvalue
}
That should not be an error, or I should at least be able to tell the
compiler "this is NOT an rvalue, even if it seems like one".
No, foo returns an lValue, however the ++ is likely wrong. The
compiler could have an ingrained belief that ++ is an assignment
operator meaning it requires an Lvalue, at which point the code is
wrong. But ++ is just an operator for the struct, so I don't know.
You are saying opposite things "foo returns an LValue" "it requires an
Lvalue, at which point the code is wrong"
Which is it?
I contend that T is an LValue type. If the compiler can't see that, it
needs to be told, or it needs to get out of the way.
I just tested a simple "incx()" function that is identical to the
operator, and it works. I can even call the operator via
foo.opUnary!"++"() and it works! So the compiler is restricting things
that are trivially circumvented.
Maybe it should be: calling a method of an rvalue, even if that method is
called via operator overload, should always be allowed. Any simple field
access should fail if the rvalue is modified. So for instance foo.x++
should fail, but foo++ should work, even if all it does is x++. Maybe if
the compiler inlines the code and sees it trivially reduces to a rejected
case, it can reject it.
-Steve