const Propagation

Julian Kranz via Digitalmars-d digitalmars-d at puremagic.com
Wed Jan 7 10:27:45 PST 2015


On Monday, 29 December 2014 at 20:24:13 UTC, Steven Schveighoffer 
wrote:
> On 12/29/14 3:11 PM, Steven Schveighoffer wrote:
>> On 12/29/14 2:07 PM, anonymous wrote:
>>> On Monday, 29 December 2014 at 13:20:39 UTC, Julian Kranz 
>>> wrote:
>>>> Thank you for your answer. This kind of thing also works for 
>>>> C++, but
>>>> that would mean that I would implement the whole visitor 
>>>> twice - one
>>>> const and one non-const version. Is that really the only 
>>>> way? Can't I
>>>> tell the D compiler that "the argument of that lambda shares 
>>>> the
>>>> const-ness of the current object"?
>>>>
>>>> D offers "inout"; this actually aims into the right 
>>>> directing, but I
>>>> guess it does not help here.
>>>>
>>>> Is there any "static if"-something construct to check the 
>>>> const-ness
>>>> of an object?
>>>
>>> There's a pattern I suggested before[1] that I'd like to 
>>> mention
>>> in addition to the template solutions Steven Schveighoffer and
>>> Daniel Kozak gave:
>>>
>>> Call the non-const overload from the const overload and cast
>>> accordingly.
>>>
>>> In your case:
>>>
>>>    void blah(void function(Hugo h) f) {
>>>      f(this);
>>>    }
>>>    void blah(void function(const Hugo h) f) const {
>>>      (cast(Hugo) this).blah(cast(void function(Hugo)) f);
>>>    }
>>
>> The problem here is, you lose your compiler checks. It's not 
>> so much
>> that "I know at this moment, mutable blah does not change 
>> anything",
>> it's "I know at this moment, and anytime in the future, 
>> mutable blah
>> does not change anything".
>>
>> Hm... I did think of another solution, using delegates:
>>
>> private void blahImpl(scope void delegate() f) const {
>>    ... // do things that don't change this
>>    f();
>>    ... // do things that don't change this
>> }
>>
>> void blah(void function(Hugo h) f) {
>>    blahImpl((){f(this);});
>> }
>>
>> And this time, I did test it, because I was curious enough :)
>>
>> While you still need the boilerplate of repeating blah for 
>> const and
>> others, you don't need to repeat the larger implementation. 
>> One thing
>> you could do is make blah a template which takes Hugo as a 
>> template
>> type, and then any function that accepts a Hugo (including a 
>> base class)
>> would be usable, and it then allows you to avoid repetition:
>>
>> void blah(T)(void function(T t) f) {
>>    blahImpl((){f(this);});
>> }
>>
>> except... drat, it doesn't compile, can't deduce T when it's 
>> const(Hugo)
>> (that doesn't make much sense). I'll look and see if there is 
>> an open
>> bug report.
>
> OK, it's not inferring the const on 'this'. It ONLY does this 
> if you have a 'this' template parameter in the template list. 
> This works:
>
> void blah(T, this _)(void function(T t) f)
>
> interesting, can someone explain this requirement?
>
> -Steve

I'd really like to know that, too ;-). Thank you again for all 
your answers!


More information about the Digitalmars-d mailing list