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:
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
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









Wusiki jeronii <wusikijeronii gmail.com> 