"not an lvalue"

Steven Schveighoffer schveiguy at yahoo.com
Mon May 2 06:56:28 PDT 2011


On Sun, 01 May 2011 09:30:34 -0400, CrypticMetaphor  
<CrypticMetaphor88 at gmail.com> wrote:

> Hi, I've been away from D for a while, but now I'm back and I'm stuck  
> with an compile time error.
>
> I've got a Matrix33 class and a Vector3 class, but something is wrong  
> with the way I return my Vector3 in my matrix class:
>
> If I do this I get an error:
>
> Matrix33 mtest = new Matrix33();
> mtest.SetIdentity();
> Vector3 test1 = new Vector3(0, 0, 0);
> Vector3 test2 = test + mtest.GetColumn(2);
>
> I get the error "Error: mtest.GetColumn(x) is not an lvalue"
>
> But the following works:
>
> Matrix33 mtest = new Matrix33();
> mtest.SetIdentity();
> Vector3 test1 = new Vector3(0, 0, 0);
> Vector3 temp = mtest.GetColumn(2);
> Vector3 test2 = test + temp;
>
> // GetColumn method
> Matrix33
> {
> // ...
>
>    /// Get a matrix column, horizontal line
>    Vector3 GetColumn(uint index)
>    {
>      assert(!(index > 2), "index is too high");
>      return new Vector3(cell[index * 3], cell[index * 3 + 1], cell[index  
> * 3 + 2]);
>    }
> // ...
> }
>
> My questions:
> What changes do I have to make to make the first example compile?

I think others have said you need to not use ref.

The solution (which is not yet properly implemented) is to use auto ref.   
The way it is supposed to work is like this:

void foo(T t); // t is passed by value (copied).  t can be an lvalue or an  
rvalue
void foo(ref T t); // t is passed by reference.  t can only be an lvalue
void foo(auto ref T t); // t is passed by reference.  t can be an lvalue  
or an rvalue.

Essentially, with auto-ref you are saying, I know there are dangers in  
passing rvalues here, but I still want to accept an rvalue by reference.

There was confusion on Walter's part as to how this was supposed to work,  
so auto ref currently doesn't act this way.

There are two workarounds I know of:

1. as you have done, convert the rvalue to an lvalue by assigning to a  
temporary
2. call the method on the rvalue.  For some reason (probably to make  
people not go insane) you are allowed to pass an rvalue by ref if you are  
calling a method on it.

i.e. this should work (don't remember vectors much, but I believe addition  
is commutative?):

Vector3 test2 = mtest.GetColumn(2) + test;

If you can't do the second method, I think method 1 is your only option.

-Steve


More information about the Digitalmars-d-learn mailing list