Finding out ref-ness of the return of an auto ref function

Arafel er.krali at gmail.com
Fri Jun 12 17:50:43 UTC 2020


On 12/6/20 18:15, Paul Backus wrote:
> 
> I think I have something that works:
> 
> ref int foo();
> int bar();
> 
> enum isLvalue(string expr) = q{
>      __traits(compiles, (auto ref x) {
>          static assert(__traits(isRef, x));
>      }(} ~ expr ~ q{))
> };
> 
> pragma(msg, mixin(isLvalue!"foo()")); // true
> pragma(msg, mixin(isLvalue!"bar()")); // false
> 
> Basically, you can pass the result of the function call to a function 
> with an `auto ref` parameter and check whether that parameter is 
> inferred as ref or not.

Thanks a lot!

I have to say, it works, it's really, really clever... but it's also 
ugly as hell, and feels like a kludge. I had already tried something 
similar with an identity function, but I couldn't make it 
compile-time... I was missing the "compiles"+"static assert" trick.

Also, it can become quite hard to check from within the function 
itself... in my case it's more or less doable because it's basically a 
forwarding, so I'm essentially doing a simple mixin, but in a more 
complex case (with perhaps even static ifs and whatever) I can see it 
becoming essentially unmanageable.

All in all, I still think something like `__traits(isRef,return)` would 
still be worth adding! After all the compiler already has all the 
information, so it's just about exposing it. I'm trying to think of a 
library solution, but I find it very hard to express "the hypothetical 
result of calling the current function with the current parameters in 
the current context".

A.


More information about the Digitalmars-d-learn mailing list