On Friday, 20 July 2018 at 14:11:23 UTC, jmh530 wrote:
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.

Hmm, on that part about the attributes copying their values, I suppose it would be sufficient if I could apply the attributes to a group of declarations. However, it didn't seem to work properly for me with UDAs, and I noticed that even some of the examples in the spec don't compile. Below is taken from section 8.5 and doesn't compile with DMD 2.081.1. (here's a version on run.dlang.org: https://run.dlang.io/is/pKHoBA)

void main()
{
    const int foo = 7;
    static assert(is(typeof(foo) == const(int)));

    const
    {
        double bar = foo + 6;
    }
    static assert(is(typeof(bar) == const(double)));
}

Reply via email to