www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - need this for name of type string

reply Andre Pany <andre s-e-a-p.de> writes:
Hi,

following coding is throwing compiler error:
   need this for name of type string

The error disappears if I delete method0.
My gut feeling is, this is a compiler bug?

---
class C
{
     static this()
     {
         getT!(typeof(this))();
     }

      Foo void method0(){}

      Foo("abc") void method1(){}
}

struct Foo
{
     string name;
}

void getT(T)()
{
     import std.traits: hasUDA, getUDAs;

     static foreach(fieldName; __traits(allMembers, T))
     {
         static if (hasUDA!(__traits(getMember, T, fieldName), 
Foo))
         {
             pragma(msg, getUDAs!(__traits(getMember, T, 
fieldName), Foo)[0].name);
         }
     }
}

void main(){}
---

Kind regards
André
Sep 10 2019
next sibling parent Alex <sascha.orlov gmail.com> writes:
On Tuesday, 10 September 2019 at 10:32:29 UTC, Andre Pany wrote:
 Hi,

 following coding is throwing compiler error:
   need this for name of type string

 The error disappears if I delete method0.
 My gut feeling is, this is a compiler bug?

 ---
 class C
 {
     static this()
     {
         getT!(typeof(this))();
     }

      Foo void method0(){}

      Foo("abc") void method1(){}
 }

 struct Foo
 {
     string name;
 }

 void getT(T)()
 {
     import std.traits: hasUDA, getUDAs;

     static foreach(fieldName; __traits(allMembers, T))
     {
         static if (hasUDA!(__traits(getMember, T, fieldName), 
 Foo))
         {
             pragma(msg, getUDAs!(__traits(getMember, T, 
 fieldName), Foo)[0].name);
         }
     }
 }

 void main(){}
 ---

 Kind regards
 André
Don't think so. In case of Foo, you don't instantiate an object. Therefore, name cannot exist. So... in this case, the UDA is a type, not an object you can query for a name. It's more the like the example with SimpleAttr on the help page [1], I think. [1] https://dlang.org/library/std/traits/get_ud_as.html
Sep 10 2019
prev sibling parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 09/10/2019 03:32 AM, Andre Pany wrote:

       Foo void method0(){}

       Foo("abc") void method1(){}
The UDA syntax allows both types and an objects. method0 uses Foo type and method1 uses a Foo object. So, if your API allows both, your code that deals with UDA must account for both. The simplest solution here is to have method0 take an object as well: Foo() void method0(){} If you want to allow for both, the UDA code must change similar to the following: static foreach(fieldName; __traits(allMembers, T)) { static if (hasUDA!(__traits(getMember, T, fieldName), Foo)) { static if (is (getUDAs!(__traits(getMember, T, fieldName), Foo)[0])) { // The UDA is the type Foo pragma(msg, "Default Foo string: ", Foo.init.name); } else { // The UDA is a Foo object pragma(msg, "Special Foo string: ", getUDAs!(__traits(getMember, T, fieldName), Foo)[0].name); } } } Ali
Sep 10 2019
parent Andre Pany <andre s-e-a-p.de> writes:
On Tuesday, 10 September 2019 at 11:20:03 UTC, Ali Çehreli wrote:
 On 09/10/2019 03:32 AM, Andre Pany wrote:

      [...]
The UDA syntax allows both types and an objects. method0 uses Foo type and method1 uses a Foo object. So, if your API allows both, your code that deals with UDA must account for both. [...]
Fantastic! Thanks a lot for the solution. Kind regards André
Sep 10 2019