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