Can't convert variables using __traits

Krzysztof Jajeśnica krzysztof.jajesnica at gmail.com
Mon Apr 18 12:20:11 UTC 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:
>> 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]);
```


More information about the Digitalmars-d mailing list