digitalmars.D - not an lvalue
- Steven Schveighoffer (62/62) Apr 23 2010 OK,
- SHOO (4/88) Apr 23 2010 I completely agree to this opinion.
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
Apr 23 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. -SteveI 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.
Apr 23 2010