digitalmars.D - Can't convert variables using __traits
- Wusiki jeronii (27/29) Apr 18 2022 Hello.
- Krzysztof =?UTF-8?B?SmFqZcWbbmljYQ==?= (33/62) Apr 18 2022 Hello,
- Wusiki jeronii (3/19) Apr 18 2022 Oohh. I've understood. Thanks
- Anonymouse (22/23) Apr 18 2022 You can use `.tupleof` too to access or foreach over individual
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
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: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]); ```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
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:Oohh. I've understood. Thanks[...]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. [...]
Apr 18 2022
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