digitalmars.D.learn - Implicit type conversion depending on assignment
- Alexander Zhirov (14/14) Mar 23 2023 Is it possible to convert such records inside the structure to
- Alexander Zhirov (6/20) Mar 23 2023 Here is an [example from the
- user1234 (25/48) Mar 23 2023 The best I can think of ATM
- user1234 (8/12) Mar 23 2023 omg, let's rewrite this...
- Alexander Zhirov (18/19) Mar 23 2023 I meant something like that. But you can't do that. I wanted
- Alexander Zhirov (5/6) Mar 23 2023 I also have thoughts about using
- apz28 (26/28) Mar 23 2023 Or abuse opBinary
- =?UTF-8?Q?Ali_=c3=87ehreli?= (27/31) Mar 23 2023 That should have been a compilation error because 'toString' does not
- =?UTF-8?Q?Ali_=c3=87ehreli?= (4/6) Mar 23 2023 D does not embrace implicit conversions. There is some support like
- zjh (4/18) Mar 23 2023 However, `rust` and`cpp` are all can!
- Jacob Shtokolov (23/37) Mar 24 2023 Here is another working variation of Ali's code, try it yourself:
- Jacob Shtokolov (4/8) Mar 24 2023 BTW, you can also `alias this` your struct value and then use
- Alexander Zhirov (3/6) Mar 24 2023 I don't quite understand what you mean? Could you show me an
- Jacob Shtokolov (21/27) Mar 24 2023 I mean, it would be the same code except that you don't define
- bachmeier (36/50) Mar 24 2023 You're limited by the use of int and float. It works just fine
- bachmeier (7/60) Mar 24 2023 `opAssign` is not needed for this code to compile, but it would
- Salih Dincer (54/66) Mar 24 2023 Have you tried using an associative array?
Is it possible to convert such records inside the structure to the assigned type? ```d struct MyVal { string value; // Here it would be possible to use an alias to this, but it can only be used 1 time } auto a = MyVal("100"); auto b = MyVal("11.2"); int MyInt = a; // Implicitly convert to target type float myFloat = b; // Implicitly convert to target type ```
Mar 23 2023
On Thursday, 23 March 2023 at 13:38:51 UTC, Alexander Zhirov wrote:Is it possible to convert such records inside the structure to the assigned type? ```d struct MyVal { string value; // Here it would be possible to use an alias to this, but it can only be used 1 time } auto a = MyVal("100"); auto b = MyVal("11.2"); int MyInt = a; // Implicitly convert to target type float myFloat = b; // Implicitly convert to target type ```Here is an [example from the documentation](https://dlang.org/spec/struct.html#alias-this), but for "several" types, for example, with a cast check and a return of the default value.
Mar 23 2023
On Thursday, 23 March 2023 at 14:05:07 UTC, Alexander Zhirov wrote:On Thursday, 23 March 2023 at 13:38:51 UTC, Alexander Zhirov wrote:The best I can think of ATM ``` struct MyVal { string value; auto opCast(T)() { import std.conv : to; return to!T(value); } } void main() { auto a = MyVal("100"); auto b = MyVal("11.2"); int MyInt = cast(int)a; float myFloat = cast(float)b; } ``` not exactly thing goal yet. The doc example you have put a link for is different, the struct with alias this a redefinition of the "alias this"'ed thing, that just cant work in what you ask in the first post.Is it possible to convert such records inside the structure to the assigned type? ```d struct MyVal { string value; // Here it would be possible to use an alias to this, but it can only be used 1 time } auto a = MyVal("100"); auto b = MyVal("11.2"); int MyInt = a; // Implicitly convert to target type float myFloat = b; // Implicitly convert to target type ```Here is an [example from the documentation](https://dlang.org/spec/struct.html#alias-this), but for "several" types, for example, with a cast check and a return of the default value.
Mar 23 2023
On Thursday, 23 March 2023 at 14:17:25 UTC, user1234 wrote:not exactly thing goal yet. The doc example you have put a link for is different, the struct with alias this a redefinition of the "alias this"'ed thing, that just cant work in what you ask in the first post.omg, let's rewrite this... not exactly the same thing as the goal yet. The doc example you have put a link for is different, the struct with "alias this" is a redefinition of the "alias this"'ed thing, that just cant work in what you ask in the first post because the type is different.
Mar 23 2023
On Thursday, 23 March 2023 at 14:19:31 UTC, user1234 wrote:omg, let's rewrite this...I meant something like that. But you can't do that. I wanted WITHOUT explicit casting. ```d struct MyVal { private string value; property auto toString(T)() { return value.to!T; } alias toString this; } auto a = MyVal("100"); auto b = MyVal("11.2"); int myInt = a; float myFloat = b; ```
Mar 23 2023
On Thursday, 23 March 2023 at 14:36:11 UTC, Alexander Zhirov wrote:I wanted WITHOUT explicit casting.I also have thoughts about using [templates](https://dlang.org/spec/template.html#this_rtti), but I don't have enough experience yet how to implement it.
Mar 23 2023
On Thursday, 23 March 2023 at 14:36:11 UTC, Alexander Zhirov wrote:On Thursday, 23 March 2023 at 14:19:31 UTC, user1234 wrote:Or abuse opBinary struct MyVal { string value; T opBinary(string op, T)(T rhs) if (op == "+") { import std.conv : convto = to; static if (is(T==int)) return convto!T(value) + rhs; else static if (is(T==float)) return convto!T(value) + rhs; else static assert(0); } alias opBinary this; } void main() { auto a = MyVal("100"); auto b = MyVal("11.2"); int MyInt = a + 0; float myFloat = b + 0.0f; }omg, let's rewrite this...
Mar 23 2023
On 3/23/23 07:36, Alexander Zhirov wrote:property auto toString(T)()The name is misleading because you want types other than string as well.alias toString this;That should have been a compilation error because 'toString' does not have a known type (because it depends on a template parameter). How can the compiler accept that 'alias this'?int myInt = a; float myFloat = b;Since you need to spell out 'int' and 'float' in some form anyway, the following would be my choice, which I did use in my code before: struct MyVal { private string value; auto to(T)() { import std.conv : to; return value.to!T; } } void main() { auto a = MyVal("100"); auto b = MyVal("11.2"); auto myInt = a.to!int; auto myFloat = b.to!float; } Should it be an error to convert 'a' to float? If so, the following modules may be helpful: https://dlang.org/phobos/std_sumtype.html https://dlang.org/phobos/std_variant.html Ali
Mar 23 2023
On 3/23/23 06:38, Alexander Zhirov wrote:Is it possible to convert such records inside the structure to the assigned type?D does not embrace implicit conversions. There is some support like 'alias this' as you mentioned but what you are looking for is not possible. Ali
Mar 23 2023
On Thursday, 23 March 2023 at 13:38:51 UTC, Alexander Zhirov wrote:Is it possible to convert such records inside the structure to the assigned type? ```d struct MyVal { string value; // Here it would be possible to use an alias to this, but it can only be used 1 time } auto a = MyVal("100"); auto b = MyVal("11.2"); int MyInt = a; // Implicitly convert to target type float myFloat = b; // Implicitly convert to target type ```However, `rust` and`cpp` are all can! [Here](http://purecpp.cn/detail?id=2342).
Mar 23 2023
On Thursday, 23 March 2023 at 13:38:51 UTC, Alexander Zhirov wrote:Is it possible to convert such records inside the structure to the assigned type? ```d struct MyVal { string value; // Here it would be possible to use an alias to this, but it can only be used 1 time } auto a = MyVal("100"); auto b = MyVal("11.2"); int MyInt = a; // Implicitly convert to target type float myFloat = b; // Implicitly convert to target type ```Here is another working variation of Ali's code, try it yourself: ```d import std.stdio; import std.conv; struct MyVal { string value; T opCast(T)() { return value.to!T; } } void main() { auto a = MyVal("100"); auto b = MyVal("11.2"); auto MyInt = a.to!int; auto myFloat = b.to!float; writeln(MyInt, ", ", myFloat); } ``` In general, all type casting and parsing stuff usually exist under `std.conv` in the standard library, so you can take advantage of it.
Mar 24 2023
On Friday, 24 March 2023 at 09:39:00 UTC, Jacob Shtokolov wrote:On Thursday, 23 March 2023 at 13:38:51 UTC, Alexander Zhirov wrote:BTW, you can also `alias this` your struct value and then use `std.conv : to` for casting, if you don't need specific casting rules.Is it possible to convert such records inside the structure to the assigned type?
Mar 24 2023
On Friday, 24 March 2023 at 09:46:26 UTC, Jacob Shtokolov wrote:BTW, you can also `alias this` your struct value and then use `std.conv : to` for casting, if you don't need specific casting rules.I don't quite understand what you mean? Could you show me an example?
Mar 24 2023
On Friday, 24 March 2023 at 09:59:47 UTC, Alexander Zhirov wrote:On Friday, 24 March 2023 at 09:46:26 UTC, Jacob Shtokolov wrote:I mean, it would be the same code except that you don't define any `opCast` or other operators for a struct, just alias the value to `this` and use `std.conv : to` directly as follows: ```d struct MyVal { string value; alias value this; } void main() { import std.stdio; import std.conv; auto a = MyVal("100"); auto b = MyVal("11.2"); auto MyInt = a.to!int; auto myFloat = b.to!float; writeln(MyInt, ", ", myFloat); } ```BTW, you can also `alias this` your struct value and then use `std.conv : to` for casting, if you don't need specific casting rules.I don't quite understand what you mean? Could you show me an example?
Mar 24 2023
On Thursday, 23 March 2023 at 13:38:51 UTC, Alexander Zhirov wrote:Is it possible to convert such records inside the structure to the assigned type? ```d struct MyVal { string value; // Here it would be possible to use an alias to this, but it can only be used 1 time } auto a = MyVal("100"); auto b = MyVal("11.2"); int MyInt = a; // Implicitly convert to target type float myFloat = b; // Implicitly convert to target type ```You're limited by the use of int and float. It works just fine for structs: ``` struct MyInt { int x; alias x this; this(MyString s) { x = s.to!int; } void opAssign(MyString s) { x = s.to!int; } } struct MyFloat { float x; alias x this; this(MyString s) { x = s.to!float; } void opAssign(MyString s) { x = s.to!float; } } struct MyString { string s; alias s this; } void main() { auto ms = MyString("100"); auto ms2 = MyString("11.2"); MyInt mi = ms; MyFloat mf = ms2; } ```
Mar 24 2023
On Friday, 24 March 2023 at 13:53:02 UTC, bachmeier wrote:On Thursday, 23 March 2023 at 13:38:51 UTC, Alexander Zhirov wrote:`opAssign` is not needed for this code to compile, but it would be if you had ``` MyInt mi; mi = ms; ```Is it possible to convert such records inside the structure to the assigned type? ```d struct MyVal { string value; // Here it would be possible to use an alias to this, but it can only be used 1 time } auto a = MyVal("100"); auto b = MyVal("11.2"); int MyInt = a; // Implicitly convert to target type float myFloat = b; // Implicitly convert to target type ```You're limited by the use of int and float. It works just fine for structs: ``` struct MyInt { int x; alias x this; this(MyString s) { x = s.to!int; } void opAssign(MyString s) { x = s.to!int; } } struct MyFloat { float x; alias x this; this(MyString s) { x = s.to!float; } void opAssign(MyString s) { x = s.to!float; } } struct MyString { string s; alias s this; } void main() { auto ms = MyString("100"); auto ms2 = MyString("11.2"); MyInt mi = ms; MyFloat mf = ms2; } ```
Mar 24 2023
On Thursday, 23 March 2023 at 13:38:51 UTC, Alexander Zhirov wrote:```d struct MyVal { string value; // Here it would be possible to use an alias to this, but it can only be used 1 time } auto a = MyVal("100"); auto b = MyVal("11.2"); int MyInt = a; // Implicitly convert to target type float myFloat = b; // Implicitly convert to target type ```Have you tried using an associative array? I feel that you will come up with a solution for your purpose from the examples below: ```d template MyContainer(string data = "") { // Container name ---^ struct Var { import std.variant; private Variant[string] values; alias values this; property { Variant opDispatch(string key)() const { return values[key]; } void opDispatch(string key, T)(T val) { values[key] = val; } } } static if(data.length > 0) { import std.format; mixin(data.format!"Var %s;"); } else { Var data; // no conflicts } } import std.stdio; void main() { enum Tarih { AY = 1, YIL = 2023 } mixin MyContainer!"date"; date.month = cast(ubyte)Tarih.AY; date.month.write("/"); assert(date["month"] != Tarih.AY); assert(date["month"].type == typeid(ubyte)); date.year = cast(short)Tarih.YIL; date.year.writeln(" in Turkish format"); assert(date["year"] != Tarih.YIL); assert(date["year"].type == typeid(short)); writefln("Date: %s/%s", date.year, date.month); } ``` SDB 79
Mar 24 2023