www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - returning 'ref inout(T)' - not an lvalue?

reply bitwise <bitwise.pvt gmail.com> writes:
Compiling the code below gives these errors:

main.d(92): Error: 
cast(inout(int))this.list.data[cast(uint)(this.pos + i)] is not 
an lvalue
main.d(101): Error: template instance 
main.Iterator!(const(List!int)) error instantiating
main.d(108): instantiated from here: first!(const(List!int))

struct Iterator(C)
{
     C list;
     int pos;
	
     alias T = typeof(list.data[0]);

     this(C list, int pos) {
         this.list = list;
         this.pos = pos;
     }

     ref inout(T) opIndex(int i) inout {
         return list.data[pos + i];
     }
}

class List(T)
{
     T[] data = new T[1];

     auto first(this This)() {
         return Iterator!This(this, 0);
     }
}

int main(string[] argv)
{
     const(List!int) c;
     auto it = c.first;
}

Is it not possible to return a ref from an inout function?
Jan 25 2017
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Wednesday, 25 January 2017 at 20:42:52 UTC, bitwise wrote:
 Is it not possible to return a ref from an inout function?
It isn't the inout that's getting you, it is the const object in main(). const(List!int) c; Make that mutable and it works. Why? Cuz the `C list` in the iterator keeps that const with it.... I'm not sure why that kills it though, the error tells me it is an internal cast that is breaking things but I don't see why that logically would. This might arguably be a bug, but you could work around it by checking for that const This and offering a different method that just returns const instead of ref.
     T[] data = new T[1];
BTW what do you think this line does? I ask because most people who use it don't get what they expect out of it....
Jan 25 2017
parent bitwise <bitwise.pvt gmail.com> writes:
On Wednesday, 25 January 2017 at 21:04:50 UTC, Adam D. Ruppe 
wrote:
 On Wednesday, 25 January 2017 at 20:42:52 UTC, bitwise wrote:
 Is it not possible to return a ref from an inout function?
It isn't the inout that's getting you, it is the const object in main(). const(List!int) c; Make that mutable and it works. Why? Cuz the `C list` in the iterator keeps that const with it.... I'm not sure why that kills it though, the error tells me it is an internal cast that is breaking things but I don't see why that logically would.
This was intentional, because I thought that due to transitivity, 'alias T' would also be const, and opIndex would return const(T) when created from a const(List!T). I just tried the following though, and it outputs 'int' rather than 'const(T)' for a const(List!T): alias T = typeof(list.data[0]); pragma(msg, T.stringof); This is not what I thought would happen. I actually changed it up like this, and things seem to work: alias T = CopyTypeQualifiers!(C, typeof(list.data[0])); ref inout(T) opIndex(int i) inout{ return list.data[pos + i]; }
 This might arguably be a bug, but you could work around it by 
 checking for that const This and offering a different method 
 that just returns const instead of ref.
Given what the solution was, I think the error message could be improved, but I'm not sure what the right approach would be.
     T[] data = new T[1];
BTW what do you think this line does? I ask because most people who use it don't get what they expect out of it....
Should be an array of 'T' with all elements set to T.init right? This was just an example - for some reason, I thought it would make things clearer. Thanks
Jan 25 2017