On Tuesday, 29 April 2014 at 06:22:34 UTC, Atash wrote:
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~!
Ignore the 'bulleted' bit. I edited that preceding section from a
list to a paragraph.