Possible to avoid downcasting?
H. S. Teoh
hsteoh at quickfur.ath.cx
Tue Dec 24 22:38:06 UTC 2019
On Tue, Dec 24, 2019 at 08:15:32PM +0000, Adam D. Ruppe via Digitalmars-d wrote:
> On Tuesday, 24 December 2019 at 19:52:44 UTC, H. S. Teoh wrote:
> > But I want to have the option of creating the tree with derived
> > class nodes instead of BaseNode. One option is to pass a factory
> > function to makeTree():
> >
> > BaseNode makeBaseNode() { return new BaseNode(...); }
>
> You can also, if this is in the class, make it virtual and have the
> child classes return instances of themselves when overriding.
Good point. But it doesn't solve the problem of the return type being
only the base class.
> > Is there a template equivalent of inout functions, where you
> > basically say "the return type depends on the template parameter,
> > but otherwise the function body is identical, so don't bother
> > creating a new instantiation, just reuse the same function body"?
>
> But this is easy enough with traditional function techniques:
>
> private void populate(Base b) { /* guts that only need to know base;
> most your makeTree function */ }
>
> public T make(T)() {
> auto t = new T();
> populate(t);
> return t;
> }
>
>
> So now the templated section is reduced to really just the constructor
> call... and realistically the compiler can pretty easily inline that
> as well.
>
> No cast, minimal duplication, easy to use on the outside.
[...]
That's a nice trick... except for the fatal wrinkle that populate() /
makeTree() needs to be recursive. Sorry, I left out this
all-too-important detail. Basically, it recursively builds the tree:
class Base {
Base* left, right;
}
class Derived : Base {}
Base makeTree(...) {
auto root = new Base;
if (someCondition) {
root.left = makeTree(...);
root.right = makeTree(...);
}
return root;
}
I can replace the 'new Base' call with a function/delegate that creates
Derived nodes instead, but how to fix the return type of makeTree
without templating the entire function?
T
--
It said to install Windows 2000 or better, so I installed Linux instead.
More information about the Digitalmars-d
mailing list