not an lvalue

SHOO zan77137 at nifty.com
Fri Apr 23 22:06:33 PDT 2010


Steven Schveighoffer さんは書きました:
> OK,
> 
> So I'm just finishing up porting dcollections into D2, and I came across 
> this sucky problem:
> 
>     range opSlice(cursor b, cursor e)
>     {
>         // for hashmap, we only support ranges that begin on the first 
> cursor,
>         // or end on the last cursor.
>         if((b == begin && belongs(e)) || (e == end && belongs(b)))
>         {
>             range result;
>             result._begin = b.position;
>             result._end = e.position;
>             return result;
>         }
>         throw new RangeError("invalid slice parameters to " ~ 
> HashMap.stringof);
>     }
> 
> 
> 
> line 500 is the if statement
> 
> 
> dcollections/HashMap.d(500): Error: function 
> dcollections.HashMap.HashMap!(uint,uint).HashMap.cursor.opEquals (ref 
> const(cursor) it) const is not callable using argument types (cursor)
> dcollections/HashMap.d(500): Error: this.begin() is not an lvalue
> dcollections/HashMap.d(500): Error: function 
> dcollections.HashMap.HashMap!(uint,uint).HashMap.cursor.opEquals (ref 
> const(cursor) it) const is not callable using argument types (cursor)
> dcollections/HashMap.d(500): Error: this.end() is not an lvalue
> 
> I originally made cursor.opEquals have this signature:
> 
> bool opEquals(cursor it) const
> 
> But the compiler complained it *must* have signature:
> 
> bool opEquals(const ref(cursor) it) const
> 
> It didn't even allow me this:
> 
> bool opEquals(const cursor it) const
> 
> So here is my dilemma.  I either do something like this, which I think 
> is completely unnecessary and detracts from the beauty of the code:
> 
>     range opSlice(cursor b, cursor e)
>     {
>         // for hashmap, we only support ranges that begin on the first 
> cursor,
>         // or end on the last cursor.
>         auto tmpb = begin;  // CRAP!
>         auto tmpe = end;    // CRAP!
>         if((b == tmpb && belongs(e)) || (e == tmpe && belongs(b)))
>         {
>             range result;
>             result._begin = b.position;
>             result._end = e.position;
>             return result;
>         }
>         throw new RangeError("invalid slice parameters to " ~ 
> HashMap.stringof);
>     }
> 
> Or I bitch and complain here until Walter changes his mind :)
> 
> So I'm going with option B.  Something's gotta give here, making me use 
> ref, and then forcing me to declare superfluous temporaries is total BS.
> 
> ---------
> 
> Here's a general test case that I can envision any custom value type 
> that defines addition and equality being susceptible to:
> 
> if(a + b == c + d)
> 
> If that doesn't work, then the lvalue rules have to change, or D will 
> have a huge wart.
> 
> -Steve

I completely agree to this opinion.
"auto ref" may become the workaround, but by this method, we must mark 
it "auto ref" for all functions that return struct. It is stupid.



More information about the Digitalmars-d mailing list