digitalmars.D - Char enum conversion
- Rekel (3/11) Jan 01 2021 The last line crashes with:
- Steven Schveighoffer (10/24) Jan 01 2021 So what's happening here is that std.conv.to is treating your 'A' as an
- Rekel (8/17) Jan 01 2021 I see why that makes sense ascii wise, however, does that ruin
- Steven Schveighoffer (29/49) Jan 01 2021 It's not. It's templating based on the base type.
- Rekel (9/12) Jan 01 2021 I meant that in case this was an issue with char when templating
- Steven Schveighoffer (18/26) Jan 01 2021 There may be some misunderstanding here. A string is an *array* and is
I'm surprised char to enum conversion is currently not possible. This, as char[] & string conversion to enum is supported.enum E{A, B} void main() char[] a = ['A']; a.to!E.writeln; "A".to!E.writeln; 'A'.to!E.writeln; // Crash }The last line crashes with:std.conv.ConvException C:\D\dmd2\windows\bin\..\..\src\phob s\std\conv.d(2058): Value (A) does not match any member value of enum 'Enum'
Jan 01 2021
On 1/1/21 12:17 PM, Rekel wrote:I'm surprised char to enum conversion is currently not possible. This, as char[] & string conversion to enum is supported.So what's happening here is that std.conv.to is treating your 'A' as an integer. What you are doing is really: 65.to!E.writeln; // 'A' is really a octet of 65 That char/wchar/dchar are treated as a standard implicit-convertible integer type is one of the failings of D I think. Another gotcha to watch out for, if your enum is string-based, there is NO WAY to use std.conv to convert from the base string to the enum type, it only goes by enum names. -Steveenum E{A, B} void main() char[] a = ['A']; a.to!E.writeln; "A".to!E.writeln; 'A'.to!E.writeln; // Crash }The last line crashes with:std.conv.ConvException C:\D\dmd2\windows\bin\..\..\src\phob s\std\conv.d(2058): Value (A) does not match any member value of enum 'Enum'
Jan 01 2021
On Friday, 1 January 2021 at 17:59:30 UTC, Steven Schveighoffer wrote:So what's happening here is that std.conv.to is treating your 'A' as an integer. What you are doing is really: 65.to!E.writeln; // 'A' is really a octet of 65 That char/wchar/dchar are treated as a standard implicit-convertible integer type is one of the failings of D I think.I see why that makes sense ascii wise, however, does that ruin templating for chars? That would seem very problematic.Another gotcha to watch out for, if your enum is string-based, there is NO WAY to use std.conv to convert from the base string to the enum type, it only goes by enum names.Im unsure about what you mean here. Do you mean that an enum with strings as assigned values cannot be converted to using any of the assigned strings? If so, how come it does work using integers?
Jan 01 2021
On 1/1/21 1:11 PM, Rekel wrote:On Friday, 1 January 2021 at 17:59:30 UTC, Steven Schveighoffer wrote:It's not. It's templating based on the base type. when passed a variable that's an enum, `to` looks at 2 possibilities: 1. The type is a string -- match against the names of the enum values 2. The type is implicitly convertible to the enum base type, look up based on the base type. Since char is not a string, but it's implicitly convertible to int (which is the default base type for enums), it uses the second overload.So what's happening here is that std.conv.to is treating your 'A' as an integer. What you are doing is really: 65.to!E.writeln; // 'A' is really a octet of 65 That char/wchar/dchar are treated as a standard implicit-convertible integer type is one of the failings of D I think.I see why that makes sense ascii wise, however, does that ruin templating for chars?That would seem very problematic.I'd have to see a more compelling example in order to agree. Using 'A' instead of "A" isn't that convincing. Note, that if 'A' is in a variable, you can generate a "string" based on it: auto nameToLookup = (&var)[0 .. 1]; nameToLookup.to!E.writeln;So for example: enum X : string { Foo = "FOO", Bar = "BAR" } // std.conv.ConvException /dlang/dmd/linux/bin64/../../src/phob s/std/conv.d(2819): X does not have a member named 'FOO' auto val = "FOO".to!X; // ok auto val2 = "Foo".to!X; How come it works for integers? Because integers are not strings, so it can distinguish what you want. When both case 1 and case 2 above are the same type, it has to pick one. -SteveAnother gotcha to watch out for, if your enum is string-based, there is NO WAY to use std.conv to convert from the base string to the enum type, it only goes by enum names.Im unsure about what you mean here. Do you mean that an enum with strings as assigned values cannot be converted to using any of the assigned strings? If so, how come it does work using integers?
Jan 01 2021
On Friday, 1 January 2021 at 18:27:05 UTC, Steven Schveighoffer wrote:I meant that in case this was an issue with char when templating in general, as I'm quite new to it I wasnt sure if that was what you meant. I guess making your char into a 1 long string is an ok workaround, and the scenario's in which you have a char with names 1 character long are, I guess, limited. Ended up using [0..1]. Thanks for the explanation.That would seem very problematic.I'd have to see a more compelling example in order to agree. Using 'A' instead of "A" isn't that convincing.
Jan 01 2021
On 1/1/21 3:27 PM, Rekel wrote:On Friday, 1 January 2021 at 18:27:05 UTC, Steven Schveighoffer wrote:There may be some misunderstanding here. A string is an *array* and is not implicitly convertible from values like char. However, an int is implicitly convertible from char. If you have an overload set like: void foo(string s) { writeln("string: ", s); } void foo(int i) { writeln("int: ", i); } foo("A"); // prints string: A foo('A'); // prints int: 65 This is all that is happening, the overload set for `to` is either string or the base type of the enum (in this case int). So 'A' matches the int, not the string. It's not an issue with templating at all, you can template on a char no problem. It's just the way `to` is implemented. My comment about not being convincing was basically a solicitation to see if you have a compelling case of why you would want to use a char to represent an enum name instead of a string. The small example you give is not that. -SteveI meant that in case this was an issue with char when templating in general, as I'm quite new to it I wasnt sure if that was what you meant.That would seem very problematic.I'd have to see a more compelling example in order to agree. Using 'A' instead of "A" isn't that convincing.
Jan 01 2021