mixin template foo(T) {
void fun(T) {}
}
struct S {
mixin foo!int;
mixin foo!string;
}
unittest {
static assert(__traits(compiles, __traits(getMember, S, "fun")));
static assert(__traits(getOverloads, S, "fun").length == 0);
S s;
s.fun(3);
}
Somehow the call to s.fun compiles, but trying to get the list of overloads fails.
Comment #1 by b2.temp — 2019-02-13T03:43:24Z
Mixed declarations are put in a nested scope. To get the overload set it's possible to use aliases to this nested scopes:
mixin template foo(T) {
void fun(T) {}
}
struct S {
mixin foo!int o1;
mixin foo!string o2;
alias fun = o1.fun;
alias fun = o2.fun;
}
unittest {
static assert(__traits(getOverloads, S, "fun").length == 2);
}
see point 5 of https://dlang.org/spec/template-mixin.html#mixin_scope
Comment #2 by simen.kjaras — 2019-02-13T07:45:19Z
Your solution requires me to change the type to get information that is already available to the compiler elsewhere.
To top it off, the behavior is inconsistent:
mixin template foo(T) {
static int fun(T) { return 0; }
}
struct S1 {
mixin foo!int;
}
unittest {
alias a = __traits(getMember, S1, "fun");
a(1); // Works fine
// Can get overloads when there's only one:
static assert(__traits(getOverloads, S1, "fun").length == 1);
}
struct S2 {
mixin foo!int;
mixin foo!string;
}
unittest {
__traits(getMember, S2, "fun")(2); // Works fine
__traits(getMember, S2, "fun")(""); // Works fine
alias a = __traits(getMember, S2, "fun");
a(2); // Error: function expected before (), not void of type void
a(""); // Error: function expected before (), not void of type void
}
struct S3 {
static int fun(int) { return 0; }
static int fun(string) { return 0; }
}
unittest {
alias a = __traits(getMember, S3, "fun");
a(3); // Works fine
a(""); // Works fine
}
Comment #3 by robert.schadek — 2024-12-13T18:59:05Z