getters and setters not an lvalue
monarch_dodra
monarchdodra at gmail.com
Wed Oct 31 09:42:25 PDT 2012
On Wednesday, 31 October 2012 at 12:46:12 UTC, maarten van damme
wrote:
> In my current code I'd like to do something ala:
>
> void main(){
> getsettest test=new getsettest();
>
> test.value+=1;
> }
>
> class getsettest{
> int myvalue;
>
> this(){
> }
>
> @property{
>
> int value(){
> return myvalue;
> }
>
> void value(int value){
> myvalue=value;
> }
> }
> }
>
> but this gives the following error:
> test.d(4): Error: test.value() is not an lvalue
>
> Is there a rationale behind this decision of not translating
> test.value+=1 to test.value= test.value +1 ?
It's not that simple as "test.value" is not an LValue, so from
the compiler's perspective "test.value = test.value + 1" calls
two different functions, that may or may not have anything to do
with each other.
The expansion "++ => +=1 => a = a + 1" works if there is only 1
lvalue the whole chain through.
Can the compiler really assume it can do that? And is it a smart
move to allow it to make that assumption. What you have there is
basically an encapsulated field, that does not leak its address:
You can take the filed, you can update it with a new value, but
you can't modify it.
If you allow "test.value+=1", then where does it end?
Is this legal?
//----
void foo(int& a) {...}
foo(test.value);
//----
Would you want the compiler to expand it into:
//----
void foo(int& a) {...}
//scope for __temp
{
auto __temp = test.value;
foo(temp);
test.value = temp;
}
//----
--------------------
IMO, if you take the time to write both functions, instead of
just:
//----
@property ref int front(){return myvalue;}
//----
Then the compiler must assume you did it for a reason, and not
mess with your code.
More information about the Digitalmars-d-learn
mailing list