I'm trying to implement the Visitor pattern and utilize template mixins to avoid boilerplate by generating visit() methods for each type. DMD goes crazy that the two visit() overloads conflict with each other, despite overloads accepting different types (A and B in my case):
//-----------------------------------
interface Visitor(types...)
{
mixin generateMethods!types;
private mixin template generateMethods(types...)
{
static if (types.length)
{
mixin generateMethod!(types[0]); // but this works: void visit(types[0]);
mixin generateMethods!(types[1..$]);
}
}
private mixin template generateMethod(T)
{
void visit(T);
}
}
alias TestVisitor = Visitor!(A, B);
mixin template AcceptVisitor()
{
void accept(TestVisitor v)
{
v.visit(this);
}
}
class A
{
mixin AcceptVisitor;
}
class B: A
{
override mixin AcceptVisitor;
}
//-----------------------------------
P.S. As a side note, can we please have "static foreach" everywhere, just like "static if"? I just want this to work:
interface Visitor(types...)
{
static foreach (T; types)
void visit(T);
}
But D doesn't allow that, so I'm forced to use recursive mixin templates. "Recursive" doesn't mean "elegant" all the time, in this case it's the opposite. Should I make a DIP or it's not gonna happen? Why is this even forbidden in the first place?
Comment #1 by kolos80 — 2016-08-22T20:00:28Z
Oh, almost forgot: it's DMD v2.071.1 and the message says:
src/main.d(26): Error: main.Visitor!(A, B).Visitor.generateMethods!(A, B).generateMethods!(B).generateMethod!(B).visit at src/main.d(16) conflicts with main.Visitor!(A, B).Visitor.generateMethods!(A, B).generateMethod!(A).visit at src/main.d(16)
Comment #2 by robert.schadek — 2024-12-13T18:49:35Z