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?


It said to install Windows 2000 or better, so I installed Linux instead.

More information about the Digitalmars-d mailing list