const Propagation

Steven Schveighoffer via Digitalmars-d digitalmars-d at puremagic.com
Mon Dec 29 12:24:12 PST 2014


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


More information about the Digitalmars-d mailing list