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