Overload dispatch by templated interface type doesn't seem to work

QAston via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Wed Jan 20 06:01:23 PST 2016


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?


More information about the Digitalmars-d-learn mailing list