www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Can't convert variables using __traits

reply Wusiki jeronii <wusikijeronii gmail.com> writes:
Hello.
I can't change variable type using __traits.
Code:
```d
     struct Users
     {
     public:
         string login;
         string name;
         string email;
         string icon;
         int type;
     }

     void somefun()
     {
         string[string] test = ["login": "login"];
         Users* user = new Users();
         foreach (member; __traits(allMembers, Users))
             if (member in test)
                 __traits(getMember, *user, member) = 
to!(typeof(member))(test[member]);
     }

```
I get the error:
 Error: cannot implicitly convert expression `to(test["type"])` 
 of type `string` to `int`
Can anoyne explains to me why I can't convert traits member? Without traits I can declare string variable and convert it to int succesfully.
Apr 18 2022
next sibling parent reply Krzysztof =?UTF-8?B?SmFqZcWbbmljYQ==?= <krzysztof.jajesnica gmail.com> writes:
On Monday, 18 April 2022 at 11:31:29 UTC, Wusiki jeronii wrote:
 Hello.
 I can't change variable type using __traits.
 Code:
 ```d
     struct Users
     {
     public:
         string login;
         string name;
         string email;
         string icon;
         int type;
     }

     void somefun()
     {
         string[string] test = ["login": "login"];
         Users* user = new Users();
         foreach (member; __traits(allMembers, Users))
             if (member in test)
                 __traits(getMember, *user, member) = 
 to!(typeof(member))(test[member]);
     }

 ```
 I get the error:
 Error: cannot implicitly convert expression `to(test["type"])` 
 of type `string` to `int`
Can anoyne explains to me why I can't convert traits member? Without traits I can declare string variable and convert it to int succesfully.
Hello, the error happens because `__traits(allMembers)` doesn't return actual struct members, it returns their names as `string`s. Because of that `typeof(member)` will always return `string`, and your code becomes equivalent to: ```d foreach(member; __traits(allMembers, Users)) if(member in test) __traits(getMember, *user, member) = to!string(test[member]); ``` then the compiler sees that you're attempting to assign a `string` to `user.type` and gives an implicit conversion error. The solution is to apply `typeof` to the actual member, not its name: ```d __traits(getMember, *user, member) = to!(typeof(__traits(getMember, *user, member)))(test[member]); ``` Obviously this is quite verbose. You can improve the readability a bit by introducing a helper function: ```d void setFromString(T)(out T member, string value) { member = to!T(value); } //later: foreach(member; __traits(allMembers, Users)) if(member in test) __traits(getMember, *user, member).setFromString(test[member]); ```
Apr 18 2022
parent Wusiki jeronii <wusikijeronii gmail.com> writes:
On Monday, 18 April 2022 at 12:20:11 UTC, Krzysztof Jajeśnica 
wrote:
 On Monday, 18 April 2022 at 11:31:29 UTC, Wusiki jeronii wrote:
 [...]
Hello, the error happens because `__traits(allMembers)` doesn't return actual struct members, it returns their names as `string`s. Because of that `typeof(member)` will always return `string`, and your code becomes equivalent to: ```d foreach(member; __traits(allMembers, Users)) if(member in test) __traits(getMember, *user, member) = to!string(test[member]); ``` then the compiler sees that you're attempting to assign a `string` to `user.type` and gives an implicit conversion error. [...]
Oohh. I've understood. Thanks
Apr 18 2022
prev sibling parent Anonymouse <zorael gmail.com> writes:
On Monday, 18 April 2022 at 11:31:29 UTC, Wusiki jeronii wrote:
 [...]
You can use `.tupleof` too to access or foreach over individual members of a struct or a class. ```d void somefun() { string[string] test = ["login" : "login", "type" : "42"]; Users* user = new Users(); assert(user.login == ""); assert(user.type == 0); foreach (i, ref member; user.tupleof) { enum memberName = __traits(identifier, Users.tupleof[i]); if (memberName in test) { member = to!(typeof(member))(test[memberName]); } } assert(user.login == "login"); assert(user.type == 42); } ```
Apr 18 2022