www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Overload dispatch by templated interface type doesn't seem to work

reply QAston <qaston gmail.com> writes:
Hi,

I have the following code:

interface Visitable(RETURN) {
	RETURN accept(Visitor!RETURN);
}

interface Exp :  Visitable!string,  Visitable!int {

}

interface Visitor(RETURN) {
	RETURN visitLit(Lit e);
	RETURN visitAdd(Add e);
}

class Lit : Exp {
	int val;
	this(int val) {
		this.val = val;
	}
	override int accept(Visitor!int v) {
		return v.visitLit(this);
	}
	override string accept(Visitor!string v) {
		return v.visitLit(this);
	}
}
class Add : Exp {
	Exp lhs, rhs;
	this(Exp lhs, Exp rhs) {
		this.lhs = lhs;
		this.rhs = rhs;
	}
	override int accept(Visitor!int v) {
		return v.visitAdd(this);
	}
	override string accept(Visitor!string v) {
		return v.visitAdd(this);
	}
}

class Eval : Visitor!int {
	override int visitLit(Lit e) {
		return e.val;
	}
	override int visitAdd(Add e) {
		return e.lhs.accept(this) + e.rhs.accept(this);
	}
}

class Print : Visitor!string {
	override string visitLit(Lit e) {
		return to!string(e.val);
	}
	override string visitAdd(Add e) {
		return "(" ~ e.lhs.accept(this) ~ " + " ~ e.rhs.accept(this) ~ 
")";
	}
}

unittest {
	auto val = new Add(new Lit(1), new Lit(6)).accept(new Eval());
	assert(val == 7);
	auto s = new Add(new Lit(1), new Lit(6)).accept(new Print());
	assert(s == "(1 + 6)");
}

Which is a dummy AST. It's an example of a visitor pattern. The 
compiler gives the following error for this code:

  Error: function Visitable!string.Visitable.accept 
(Visitor!string) is not callable using argument types (Eval)
  Error: function Visitable!string.Visitable.accept 
(Visitor!string) is not callable using argument types (Eval)

in Eval.visitAdd.

When i swap the order of implemented interfaces in Exp, there's a 
symmetrical error in Print.visitAdd with Visitor!int.

To me this suggests that the dispatch by templated interface type 
Visitor!(RETURN) doesn't work. IMO the order of interfaces 
shouldn't matter here and the code should simply work.

Any ideas?
Jan 20 2016
parent QAston <qaston gmail.com> writes:
On Wednesday, 20 January 2016 at 14:01:23 UTC, QAston wrote:
 To me this suggests that the dispatch by templated interface 
 type Visitor!(RETURN) doesn't work. IMO the order of interfaces 
 shouldn't matter here and the code should simply work.

 Any ideas?
I'm on 2069.2 and when i remove one of the offending classes (Print or Eval) class the other compiles and works.
Jan 20 2016