Getting the overload set of a template
Arafel
er.krali at gmail.com
Mon Apr 23 16:16:09 UTC 2018
I think both versions are not equivalent at all. Consider [1]:
```
import std.meta;
void main()
{
pragma(msg, __traits(getMember, A, "Foo1").stringof); // Foo1(int
N) if (N & 1)
pragma(msg, __traits(getAttributes, __traits(getMember, A,
"Foo1"))[0]); // tuple("int", "odd")
alias f1a = Instantiate!(__traits(getMember, A, "Foo1"), 1); //
This is expected
pragma(msg, f1a); // A
alias f1b = Instantiate!(__traits(getMember, A, "Foo1"), "+"); //
Why would I know that I can even instantiate?? Also, can I haz UDA plz?
pragma(msg, f1b); // B
}
class A {
@("int", "odd")
template Foo1(int N) if (N & 1) {
enum Foo1 = "A";
}
@("string", "+")
template Foo1(string op) if (op == "+") {
enum Foo1 = "B";
}
}
```
In this case you could perhaps use an alias parameter to achieve a
similar effect. I haven't tried it but it would be really messy, if it
even works.
What seems clear to me from this case is that *internally* the compiler
sees a *set* of "overloads" (change that word if you think it should
only apply to functions), but I can only get the first of the batch!
For example, I might want to add some information in the UDA on how to
instantiate the template, but then I can't get the UDA either. I'm sure
it's somewhere, just that we get no access to it, and that shouldn't be
too hard to add.
I think this clarifies a bit the problem I see.
A.
[1]: https://run.dlang.io/is/zRDHGn
On 04/23/2018 05:00 PM, Alex wrote:
> On Monday, 23 April 2018 at 14:22:13 UTC, Simen Kjærås wrote:
>> As with all things D, the only real spec is the compiler source code.
>> :p :(
>
> :p
>
>> Proving that two templates are equivalent is in general impossible,
>> since any amount of wasted computation could be performed before the
>> end result is returned, and inputs must be tested exhaustively for the
>> proof to be valid. The fact that two templates give the same result in
>> one special case does not mean that they are equivalent in the general
>> case, and the compiler needs to care about the general case.
>
> Ok, thats exactly the point. If you have functions
>
> void foo() {}
> void foo(int n) {}
>
> There is no ambiguity which function will be chosen if it will be called.
>
> If you have templates
>
> // form 1
> template Foo(int N) if (N & 1) {} // A
> template Foo(int N) if (!(N & 1)) {} // B
>
> OR
>
> // form 2
> template foo(int N)
> {
> static if(N & 1){} // A
> else{} // B
> }
>
> There is also no ambiguity which will be called.
>
> However, getOverloads will behave differently.
>
> This is not bad at all. But you have to admit, that while now, there is
> no way to distinguish form 1 and form 2, with the new getOverloads there
> will be.
> This seems strange to me, because there is no reason to distinguish form
> 1 and form 2. (Because the callable code, which will be generated is the
> same, I hope... ?)
>
> So, in particular, I'm not against the feature. And if the equivalence
> between form 1 and form 2 is gone, so what. But I don't understand the
> reasoning why something which is now equal won't be equal any more later?
More information about the Digitalmars-d-learn
mailing list