hasUDA with this

jmh530 john.michael.hall at gmail.com
Fri Jul 20 14:11:23 UTC 2018


On Friday, 20 July 2018 at 07:25:23 UTC, Simen Kjærås wrote:
>
> UDAs apply to symbols. When you pass something to a function, 
> the symbol does not go with the value, and thus that UDA goes 
> away. It's similar to assigning to a different variable:
>
>     import std.traits : hasUDA;
>     @("foo")
>     Foo foo1;
>     Foo foo2 = foo1;
>     assert(!hasUDA!(foo2, "foo"));
>
> Since UDAs are compile-time constructs, they really can't 
> follow values around in that way. Consider:
>
> void main(string[] args) {
>     @("foo")
>     Foo foo1;
>     @("bar")
>     Foo foo2;
>     Foo foo3 = (args.length % 2) ? foo1 : foo2;
>     assert(hasUDA!(foo3, "foo")); // Would you expect this to 
> pass or fail?
> }
>
> Timoses first checkUDA function is exactly what I would suggest 
> you use.
>
> --
>   Simen

That the UDAs don't copy with the values potentially throws my 
idea into the crapper...

Anyway, what I really wanted to do is change behavior of the 
struct, at compile-time, based on a UDA. For instance, what I 
really want is more like:

struct Foo
{
     static if (hasUDA!(this, DisableCasting))
     {
         @disable T opCast(T) { }
     }
}

So that if the instance has the particular UDA, then some kind of 
error would be thrown at compile-time that opCast was disabled. I 
don't really need anything at run-time. Obviously, I could do 
this as a template with a compile-time switch. I just wanted to 
see if it was possible with a UDA because then I could apply it 
to many different structs by just adding a template mixin of the 
above. I wouldn't need to make them different types. All 
functions that currently use them would work, unless there is a 
cast, in which case you know that at compile-time.


More information about the Digitalmars-d-learn mailing list