Why D const is annoying
Steven Schveighoffer
schveiguy at yahoo.com
Sun Dec 11 08:23:18 PST 2011
On Sat, 10 Dec 2011 14:47:15 -0500, Mehrdad <wfunction at hotmail.com> wrote:
> On 12/10/2011 3:33 AM, Walter Bright wrote:
>> On 12/10/2011 3:14 AM, Mehrdad wrote:
>>> ... and another... (yes, this one _IS_ a const issue)
>>>
>>> struct S { int opApply(scope int delegate(ref inout(int)) dg) inout {
>>> return 0; } }
>>> void main()
>>> {
>>> foreach (i; S()) { }
>>> }
>>>
>>> Error: inout on parameter means inout must be on return type as well
>>> (if from D1
>>> code, replace with 'ref')
>>
>> Right. inout has no point if it also does not appear on the return type.
>>
>> The purpose of inout is to transfer the 'constness' of the argument to
>> the return type. If inout isn't on the return type somewhere, there's
>> likely a design mistake in your code. It's like having:
>>
>> {
>> a + b;
>> }
>>
>> Which is an error in D because such is pointless.
>
> Oh yeah, I just realized -- I think you missed the _second_ 'inout'.
> It's indeed on a parameter! It's just on the implicit 'this' parameter,
> not on an explicit one. This is a bug (IMO, arising from the fact that
> inout() is treated like a type constructor, whereas it shouldn't be).
I'll split it out so it's easier to see:
alias int delegate(ref inout(int)) dgtype;
int opApply(dgtype dg) inout;
Notice that neither dgtype or opapply has inout on the return type. Hence
the error.
However, I know what you are trying to do. You are trying to say that
"while inside the delegate, use the constancy of the actual type". It
won't work, because inout applies as const the *entire time* you are
inside an inout function. Even when calling an external delegate.
opApply is not like a range, it executes the foreach loop entirely inside
the context of opApply. That is one advantage of ranges (but it's hard to
take advantage, since you would currently have to define a range for each
const type).
AFAIK, the only way to do this properly is to have two different versions,
one for const, one for non-const.
And yes, inout should be a type constructor. It has to be, I don't know
where you got the idea it shouldn't.
-Steve
More information about the Digitalmars-d
mailing list