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.
-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.
Apr 23 2010








SHOO <zan77137 nifty.com>