not an lvalue

Steven Schveighoffer schveiguy at yahoo.com
Fri Apr 23 20:18:45 PDT 2010


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



More information about the Digitalmars-d mailing list