On 11/29/2010 11:22 PM, Max Samukha wrote:
On 11/29/2010 08:58 PM, Steven Schveighoffer wrote:
Most likely not. How do you say that the 'draw' function switches the
widget to a different parameterized type? With const, you can just slap
a const on the end of the function.
Here is some example of what I mean:
class Widget
{
mutable Window location;
int x, y, width, height;
void draw() const { location.drawRectangle(x, y, width, height); }
}
where Window.drawRectangle is not a const function.
-Steve
I think we could try to devise a library solution. For example, the
problem could be solved with a templated struct + "alias this", provided
bugs in "alias this" are fixed. The following code works even with the
current implementation (dmd 2.050):
struct Mutable(T)
{
T value;
@property ref Unqual!T mutable() const
{
auto p = cast(Unqual!T*)&value;
return *p;
}
alias mutable this;
ref opAssign(U)(auto ref U v) const
{
return mutable() = v;
}
}
class Window
{
void drawRectangle(int x, int y, int width, int height)
{
writeln("Draw");
}
}
class C
{
int x, y, width, height;
Mutable!Window location;
this()
{
location = new Window;
}
void draw() const { location.drawRectangle(x, y, width, height); }
}
void main()
{
const C c = new C;
c.draw();
}
(opAssign shouldn't be necessary. The compiler should properly forward
the assignment operation to the value returned by "mutable")
"C" is a remnant of the test I used locally. Should be renamed to Widget.
p temporary in "mutable()" should not be necessary but compilation fails
without it. Also, can a cast from lvalue result in lvalue wherever this
makes sense?