Dealing with raw types as attributes

Neia Neutuladh neia at ikeran.org
Thu Nov 1 16:14:45 UTC 2018


The spec says that a user-defined attribute must be an expression, but DMD 
accepts a wide range of things as UDAs:

  struct Foo { string name = "unknown"; }
  @Foo int bar;

`bar` has the *type* Foo as an attribute. It's not an *instance* of Foo. 
So if I try to look at the UDAs:

  static foreach (uda; __traits(getAttributes, bar))
  {
    static if (is(typeof(uda) == Foo))
    {
      pragma(msg, "bar is @Foo");
    }
  }

That just doesn't work; typeof(Foo) isn't anything, so is(typeof(Foo) == 
Foo) is false.

I can change my code to read `static if (is(uda == Foo))`. But that 
obviously fails:

  @Foo("customName") int bar2;

What do you do to handle this?

My current workaround is to make the attribute into a struct instance and 
use opCall in lieu of constructors:

  struct _Foo
  {
    string name;
    _Foo opCall(string name)
    {
      _Foo f;
      f.name = name;
      return f;
    }
  }
  enum _Foo Foo = _Foo.init;

Now I can use `static if (is(typeof(uda) == _Foo))` and it always works. 
But are there better options? Any obvious flaws?


More information about the Digitalmars-d-learn mailing list