const Propagation

Steven Schveighoffer via Digitalmars-d digitalmars-d at puremagic.com
Tue Dec 30 04:27:11 PST 2014


On 12/29/14 9:12 PM, Matt Soucy wrote:
> On 12/29/2014 02: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);
>>     }
>>
>> This is safe as long as the non-const overload does not mutate
>> the object when f doesn't. BUT you have to make sure of that
>> yourself; the compiler can't help anymore.
>>
>> [1]
>> http://stackoverflow.com/questions/22442031/how-to-make-a-template-function-const-if-the-template-is-true/22442425#22442425
> Wait, is there a reason that you cast away const instead of adding it? I haven't done too much with D const lately, but in C++ I know that I would have the non-const version call the const version instead - seems a bit safer, and the compiler can check it a bit beter.
>

It would still require a cast. Remember the function pointer passed to 
non-const blah requires a non-const Hugo. So you would have to cast at 
least the function pointer to void function(const(Hugo)). This doesn't 
sit as well as casting the other way (you can always call a function 
that takes a const Hugo with a non-const Hugo), although practically 
speaking, there isn't any damage done. However, the call of f inside the 
const blah function would violate const. If f were marked as pure, this 
could be actually damaging.

Either solution looks ugly and error-prone to me. I like the template 
solution the best, either as a template this member or a UFCS template 
function call. The delegate solution I posted earlier is neat, but seems 
too inelegant.

-Steve


More information about the Digitalmars-d mailing list