December 24, 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.