www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - template UDA

reply "bitwise" <bitwise.pvt gmail.com> writes:
Currently this will compile
Note:
-no type is supplied to  MyAttribute
-"instantiated" will not be printed

struct MyAttribute(T) {
     pragma(msg, "instantiated");
}

 MyAttribute class SomeClass { }

void main(string[] args) {
     A a = new A();
}

Is there any real(and plausible) use case where providing a 
template with no argument as a UDA would be useful?

If not, could the above usage be made to instantiate MyAttribute 
using the type of whatever it's applied to?

So in the above example, MyAttribute would be(or attempted to be) 
instantiated with type 'SomeClass'.

Currently, you can achieve this(annoyingly and redundantly) like 
this:

 MyAttribute!SomeClass class SomeClass { }

So if there is no valid usage for untyped template UDA's, can D 
be made to act as I am proposing?
Sep 07 2015
parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Monday, 7 September 2015 at 22:00:07 UTC, bitwise wrote:
 Is there any real(and plausible) use case where providing a 
 template with no argument as a UDA would be useful?
Yes, you actually wrote it yourself!
  MyAttribute!SomeClass class SomeClass { }
That right there is a reason. When you are looking for UDAs, you look for declarations. The usage code looks like: foreach(member; getMembers!module) if(member.hasUDA!(MyAttribute)) { // do something } The beauty of it is that member is right there! So your reflection code could instantiate it right there: // do something becomes... MyAttribute!(member); so it instantiates the template with the given member in the reflection code itself.
Sep 07 2015
next sibling parent "bitwise" <bitwise.pvt gmail.com> writes:
On Monday, 7 September 2015 at 22:03:13 UTC, Adam D. Ruppe wrote:
 On Monday, 7 September 2015 at 22:00:07 UTC, bitwise wrote:
 Is there any real(and plausible) use case where providing a 
 template with no argument as a UDA would be useful?
Yes, you actually wrote it yourself!
  MyAttribute!SomeClass class SomeClass { }
That right there is a reason. When you are looking for UDAs, you look for declarations. The usage code looks like:
I kinda understand what you're saying, but I still don't think there is any benefit to tagging something with a template which has no type. The attribute in the above example doesn't need to be a template. I imagine that if I were to search for a template UDA, the next step would probably be to enumerate the template parameters and take special action. Otherwise, the type is not needed. I suppose a template UDA could either have some args, or no args, but I can't imaging a use case where this would actually happen.
 foreach(member; getMembers!module)
   if(member.hasUDA!(MyAttribute)) {
       // do something
   }

 The beauty of it is that member is right there! So your 
 reflection code could instantiate it right there:

   // do something becomes...
   MyAttribute!(member);

 so it instantiates the template with the given member in the 
 reflection code itself.
My goal is not to have this reflection code at all(the loop which looks through the module instantiating things). I want the attribute itself to do that. Example: struct Reflection { string typeName; string[] members; static Reflection[string] reflections; } struct Reflected(T) { static this() { string[] members; foreach(memberName; __traits(allMembers, T)) { members ~= memberName; } enum typeName = fullyQualifiedName!T.stringof[1..$-1]; writeln("registering type: " ~ typeName); Reflection.reflections[typeName] = Reflection(typeName, members); } } Reflection* reflect(Object obj) { writeln("retrieving type for: " ~ typeid(obj).toString); return typeid(obj).toString in Reflection.reflections; } Reflected!A class A { int x; float y; string z; } void main(string[] args) { A a = new A(); foreach(n; a.reflect.members) writeln(n); } But I would like to have the attribute pick up the type that's attached. I saw an example, in another post that went something like this: struct MyAttribute(T = _UDA_OBJECT_) { } This would be acceptable too, but for some reason, the response received almost no attention. Bit
Sep 07 2015
prev sibling next sibling parent "bitwise" <bitwise.pvt gmail.com> writes:
On Monday, 7 September 2015 at 22:03:13 UTC, Adam D. Ruppe wrote:
 [...]
A more useful example: http://dpaste.dzfl.pl/82a3d65be4be
Sep 07 2015
prev sibling parent "bitwise" <bitwise.pvt gmail.com> writes:
On Monday, 7 September 2015 at 22:03:13 UTC, Adam D. Ruppe wrote:
 [...]
digging deeper, this very contrived example compiles: struct S(T) { int x; } auto fun(alias T, S)(S x) { return T!S(x); } void main(string[] args) { auto s = fun!S(123); writeln(s.x); } So I suppose the existing behaviour shouldn't really be considered a bug. This syntax would sure be nice though: struct MyAttribute(T = _UDA_TARGET_) { }
Sep 07 2015