www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Implicit type conversion depending on assignment

reply Alexander Zhirov <azhirov1991 gmail.com> writes:
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
next sibling parent reply Alexander Zhirov <azhirov1991 gmail.com> writes:
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
parent reply user1234 <user1234 12.de> writes:
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:
 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.
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.
Mar 23 2023
parent reply user1234 <user1234 12.de> writes:
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
parent reply Alexander Zhirov <azhirov1991 gmail.com> writes:
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
next sibling parent Alexander Zhirov <azhirov1991 gmail.com> writes:
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
prev sibling next sibling parent apz28 <home home.com> writes:
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:
 omg, let's rewrite this...
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; }
Mar 23 2023
prev sibling parent =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
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
prev sibling next sibling parent =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
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
prev sibling next sibling parent zjh <fqbqrr 163.com> writes:
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
prev sibling next sibling parent reply Jacob Shtokolov <jacob.100205 gmail.com> writes:
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
parent reply Jacob Shtokolov <jacob.100205 gmail.com> writes:
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:
 Is it possible to convert such records inside the structure to 
 the assigned type?
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.
Mar 24 2023
parent reply Alexander Zhirov <azhirov1991 gmail.com> writes:
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
parent Jacob Shtokolov <jacob.100205 gmail.com> writes:
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:
 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?
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); } ```
Mar 24 2023
prev sibling next sibling parent reply bachmeier <no spam.net> writes:
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
parent bachmeier <no spam.net> writes:
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:
 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; } ```
`opAssign` is not needed for this code to compile, but it would be if you had ``` MyInt mi; mi = ms; ```
Mar 24 2023
prev sibling parent Salih Dincer <salihdb hotmail.com> writes:
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