| |
| Posted by H. S. Teoh in reply to realhet | PermalinkReply |
|
H. S. Teoh
Posted in reply to realhet
| On Wed, May 13, 2020 at 12:26:21PM +0000, realhet via Digitalmars-d-learn wrote:
> Hello,
>
> Is there a way to the following thing in a class instead of a struct?
>
> --------------------------------------
> static struct Point
> {
> int x, y;
>
> void toString(W)(ref W writer, scope const ref FormatSpec!char f)
> if (isOutputRange!(W, char))
> {
> // std.range.primitives.put
> put(writer, "(");
> formatValue(writer, x, f);
> put(writer, ",");
> formatValue(writer, y, f);
> put(writer, ")");
> }
> }
> --------------------------------------
>
> I think the problem is that the toString() in a class is virtual, and don't let me to have multiple overloaded methods.
>
> Is there a way to let format() deal with classes too?
[...]
The main issue is that template functions cannot be virtual. So to make it work for classes, you need to forward toString to a virtual function implemented by subclasses. Here's one way to do it:
class Base {
// virtual method implmented by subclasses
abstract void toStringImpl(scope void delegate(const(char)[]) sg,
scope const ref FormatSpec!char f);
void toString(W)(ref W writer, scope const ref FormatSpec!char f) {
// forward to virtual method
toStringImpl((s) => formattedWrite(writer, s), f);
}
}
T
--
If you want to solve a problem, you need to address its root cause, not just its symptoms. Otherwise it's like treating cancer with Tylenol...
|