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.