http://d.puremagic.com/issues/show_bug.cgi?id=7543
--- Comment #12 from Boscop <kingbos...@gmail.com> 2012-03-09 16:21:28 PST --- (In reply to comment #7) > (In reply to comment #6) > > (In reply to comment #5) > > > (In reply to comment #4) > > > > You can't do: > > A delegate(inout(A)) dg = (immutable(A) a) => new B(a); > > You claimed I could. > > Boskop wrote: > > B delegate(immutable(A)) <: A delegate(inout(A)) This is wrong, I didn't realize that I accidentally wrote that, sorry. What I wrote above this (and in comment 6) was right: Given R2 <: R1, R2 delegate(inout(T)) <: R1 delegate(immutable(T)) (because of argument contravariance and immutable(T) <: inout(T)). I didn't know at first that you wanted to point this out (probably was too distracted by your code example). (In reply to comment #8) > I think the claim that the reporter is actually making is that the inout > constancy of the delegate parameter should vary with that of this. In other > words, > > int opApply(int delegate(ref inout(int)) dg) inout > > should be callable as if it's any one of these: > > int opApply(int delegate(ref int) dg) > int opApply(int delegate(ref const(int)) dg) const > int opApply(int delegate(ref immutable(int)) dg) immutable The problem is more deep-rooted. You can only pass delegates to opApply that take a supertype of "ref inout(int)" as argument, but immutable(T) <: inout(T) and const(T) <: inout(T), and T <: inout(T). If it were possible to use inout that way, you would have to enable implicit casts from T to immutable(T) (T <: immutable(T)) but you can't do that because functions taking an immutable arg assume that it's not changed outside! There is no way to have inout delegates like you want without enabling implicit casts from T to immutable(T)! But we don't need to enable implicit casts from T to immutable(T). We can have our cake and eat it, too! Now this is the important thing to notice: In the case with opApply you actually want to transfer the constness of the this object to the argument to dg! foreach (e; new immutable(C)([1,2,3])) opApply takes ONLY a "int opApply(int delegate(ref immutable(int)) dg) immutable" foreach (e; new const(C)([1,2,3])) opApply takes ONLY a "int opApply(int delegate(ref const(int)) dg) const" foreach (e; new C([1,2,3])) opApply takes ONLY a "int opApply(int delegate(ref int) dg)" So we need a way to transfer the constness of the this object to declarations within the class. This is basically inout for types (inout_t). (It's related to the inout that is written after method signatures, but can now be be transferred to arbitrary declarations). So, with inout_t you would write: class C { int[] arr; this(int[] a){arr = a;} int opApply(int delegate(ref inout_t(int)) dg) inout { foreach(ref e; arr) if(auto r = dg(e)) return r; return 0; } } BTW: If D didn't have transitive const, you could implement it with inout_t like this: struct S{inout_t(S)* next;} -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------