typeof(func!0) != typeof(func!0())

Steven Schveighoffer schveiguy at gmail.com
Mon Aug 22 16:36:41 UTC 2022


On 8/22/22 12:19 PM, Andrey Zherikov wrote:
> On Monday, 22 August 2022 at 15:20:46 UTC, Paul Backus wrote:
>> On Monday, 22 August 2022 at 14:43:24 UTC, Andrey Zherikov wrote:
>>> But the question is still opened: why is `typeof(U().func!0)` not the 
>>> same as `typeof(U().func!0())`?
>>
>> Probably because if it were the same, it would be completely 
>> impossible to introspect on the type of `U.func!0` directly. The 
>> closest you could get would be to examine `typeof(&U.func!0)`; i.e., 
>> the type of the function pointer rather than the function itself.
>>
>> I'm not totally convinced that the current behavior is the correct 
>> decision here, but there is a real tradeoff.
> 
> I have an impression that template function can be called without 
> parenthesis if it doesn't have run-time parameters so `func!0` is the 
> same as `func!0()`. Am I wrong?
> 
> 
> If we consider free function vs. member function, why is 
> `typeof(u.func!0)` not the same as `typeof(u.func2!0)` here?
> ```d
> struct U
> {
>      ref U func(int i)() { return this; }
> }
> ref U func2(int i)(ref U u) { return u; }
> 
> void main()
> {
>      U u;
>      pragma(msg, typeof(u.func!0));    // pure nothrow @nogc ref @safe 
> U() return
>      pragma(msg, typeof(u.func2!0));    // U
> }
> ```
> 
> Is `typeof(u.func2!0)` correct in this case? If so then I'll just 
> convert my API to free-standing functions and everything will work as a 
> magic (without my own implementation of `getUDA`).

It's not magic. It's UFCS.

in the case of the struct function, there is an ambiguity. Do you mean 
the function named `func` in the *namespace* of `u` (which is actually 
`U`)? Or do you mean to call `func` *using* `u`? The D compiler opts for 
the former.

However, with `func2`, there is no `func2` in u's namespace. So the only 
option is an actual call.

-Steve


More information about the Digitalmars-d-learn mailing list