listing template function overloads for use in compile time decisions

Atash via Digitalmars-d digitalmars-d at puremagic.com
Mon Apr 28 23:22:33 PDT 2014


Let's say that we have a struct `A` that contains some template 
function named `fn` template-parameterized on its argument types:

struct A {
...
void fn(A)(auto ref A a) { ... }
...
}

I cannot get a handle on `fn` as an alias when searching for 
overloads of the string "fn" in `A` via 
`__traits(getOverloads,A,"fn")`. This makes sense, obviously, 
because `fn` doesn't really 'exist' as a template.

But the compiler can, nevertheless, generate a proper 
implementation of `fn` depending on its argument(s). It doesn't 
have to create the code, as with e.g. `__traits(compiles, 
A.init.fn(0))`. While it doesn't make sense to list overloads of 
a given name when they're templates, it does make sense that 
given some argument types and qualifiers all candidate functions 
can be easily enumerated. I can't find such a feature, however.

Moreover, I cannot figure out how one could acquire a handle on 
even *just* the best match for a given function name with some 
given argument types.

With this, library writers could perform their own overload 
resolution without enforcing the use of wrapper classes when 
trying to plug one library into another library, ex. lib A has 
struct A with `fn` and lib B has struct B with `fn` and they have 
functions `fn` that accept each other and we want to choose the 
one that partially specializes on the other over the one that 
doesn't. It's basically the decision process behind the rewriting 
that occurs with a.opCmp(b) vs. b.opCmp(a), but fully emulated in 
the presence of templates without extra client-code-side hints 
and taking into account granularity finer than the four levels of 
overload resolution. It moves glue-code (or glue-behavior like 
argument ordering to a library function) from the user to the 
library writer, and allows that glue-code to be generic.

Is this a facility that is present in D, and I missed it? Are any 
of the above bulleted use-cases manageable with present-day D?

I'm kind of an obsessive metaprogramming-fiend, so this little 
issue is strangely vexing. I've come up with an idea for a 
solution, and am attempting to implement it, but it's 
extraordinarily hackish. It assumes that the name `fn` when 
called can be entirely resolved with its arguments by looking at 
the arguments' types and their template parameters (if any) and 
implicit target conversions (and their template parameters [if 
any]). I'm seeing in my head a combinatoric blow-up from the 
possible orderings of template arguments in the template 
declaration of `fn`, so... yeah. Kinda would like a __traits 
thing that gets all possible resolutions of a symbol in a call 
expression.

Thanks for your time~!


More information about the Digitalmars-d mailing list