www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - std.conv.to

reply harakim <harakim gmail.com> writes:
I can generically convert a string to a type using to!type. I 
have a read function that does that. I have simplified the 
example below:

```d
	int readNumber()
	{
		return read!int(val => to!int(val), "number");
	}

	string readTime()
	{
		return read!string(val => toTime(val), "time");
	}

	private T read(T)(T function(string) transform, string typeName)
	{
	    string input = readln();
             return transform(input);
	}
```
However, I want to be able to convert my own custom types as 
well. How do I do that? Is there an operator overload I need to 
override for that? Do I have to static if on the template type 
and call the object?
Jun 17 2022
parent reply harakim <harakim gmail.com> writes:
On Friday, 17 June 2022 at 12:31:45 UTC, harakim wrote:
 I can generically convert a string to a type using to!type. I 
 have a read function that does that. I have simplified the 
 example below:

 ```d
 	int readNumber()
 	{
 		return read!int(val => to!int(val), "number");
 	}

 	string readTime()
 	{
 		return read!string(val => toTime(val), "time");
 	}

 	private T read(T)(T function(string) transform, string 
 typeName)
 	{
 	    string input = readln();
             return transform(input);
 	}
 ```
 However, I want to be able to convert my own custom types as 
 well. How do I do that? Is there an operator overload I need to 
 override for that? Do I have to static if on the template type 
 and call the object?
I have no idea why I was stuck on this problem for so long. I can specify anything I want in the transform and I even do in my own example lol. I am still curious if there is a way to make your type work with to!MyCustomType(source)
Jun 17 2022
next sibling parent reply bauss <jj_1337 live.dk> writes:
On Friday, 17 June 2022 at 12:48:56 UTC, harakim wrote:
 On Friday, 17 June 2022 at 12:31:45 UTC, harakim wrote:
 I can generically convert a string to a type using to!type. I 
 have a read function that does that. I have simplified the 
 example below:

 ```d
 	int readNumber()
 	{
 		return read!int(val => to!int(val), "number");
 	}

 	string readTime()
 	{
 		return read!string(val => toTime(val), "time");
 	}

 	private T read(T)(T function(string) transform, string 
 typeName)
 	{
 	    string input = readln();
             return transform(input);
 	}
 ```
 However, I want to be able to convert my own custom types as 
 well. How do I do that? Is there an operator overload I need 
 to override for that? Do I have to static if on the template 
 type and call the object?
I have no idea why I was stuck on this problem for so long. I can specify anything I want in the transform and I even do in my own example lol. I am still curious if there is a way to make your type work with to!MyCustomType(source)
Just add a constructor to your type that takes the value of what you want to convert. Working example: ```d struct Foo { int value; this(int v) { value = v; } this(string v) { this(to!int(v)); } } void main() { auto foo = to!Foo("123"); writeln(foo.value); } ```
Jun 17 2022
next sibling parent reply Salih Dincer <salihdb hotmail.com> writes:
On Friday, 17 June 2022 at 12:53:53 UTC, bauss wrote:
 Just add a constructor to your type that takes the value of 
 what you want to convert.
Isn't foo and bar the same thing? I don't understand what's the difference! By the way, what's the question? Is this the answer to the question? ```d void main() { auto foo = to!Foo("123"); //?? typeid(foo).writeln(": ", foo); assert("123".to!Foo == foo); assert(123.to!Foo == foo); auto bar = Foo("321"); typeid(bar).writeln(": ", bar); assert("321".to!Foo == bar); assert(321.to!Foo == bar); } ``` SDB 79
Jun 17 2022
parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 6/17/22 10:04, Salih Dincer wrote:

 Isn't foo and bar the same thing?  I don't understand what's the
 difference!
    auto foo = to!Foo("123"); //??
    auto bar = Foo("321");
Yes, they are the same thing. The OP was looking for a generic way of converting any type to any other type as long as there is a way. (Think a function template.) std.conv.to can do that because it considers the constructors as well. Ali
Jun 17 2022
parent Salih Dincer <salihdb hotmail.com> writes:
On Friday, 17 June 2022 at 18:40:59 UTC, Ali Çehreli wrote:
 On 6/17/22 10:04, Salih Dincer wrote:

 Isn't foo and bar the same thing?  I don't understand what's
the
 difference!
 ```d
    auto foo = to!Foo("123"); //??
    auto bar = Foo("321");
 ```
Yes, they are the same thing.
But (!) `to!` inconsiderately smuggled into the code is bubble. So we will obviously be deceived at a later moment. Thereby making nonsense further clamour for shorten...:) Then how did the evolution of the code evolve into the current form? ```d auto zar = "123".to!Foo; auto bar = to!(Foo)("123"); auto foo = to!Foo("123"); // <-- this line is bubble ``` SDB 79
Jun 17 2022
prev sibling parent harakim <harakim gmail.com> writes:
On Friday, 17 June 2022 at 12:53:53 UTC, bauss wrote:
 Just add a constructor to your type that takes the value of 
 what you want to convert.

 Working example:

 ```d
 struct Foo
 {
     int value;

     this(int v)
     {
         value = v;
     }

     this(string v)
     {
         this(to!int(v));
     }
 }

 void main()
 {
     auto foo = to!Foo("123");

     writeln(foo.value);
 }
 ```
D is full of good surprises. Thanks.
Jun 17 2022
prev sibling parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 6/17/22 8:48 AM, harakim wrote:
 On Friday, 17 June 2022 at 12:31:45 UTC, harakim wrote:
 I can generically convert a string to a type using to!type. I have a 
 read function that does that. I have simplified the example below:

 ```d
     int readNumber()
     {
         return read!int(val => to!int(val), "number");
     }

     string readTime()
     {
         return read!string(val => toTime(val), "time");
     }

     private T read(T)(T function(string) transform, string typeName)
     {
         string input = readln();
             return transform(input);
     }
 ```
 However, I want to be able to convert my own custom types as well. How 
 do I do that? Is there an operator overload I need to override for 
 that? Do I have to static if on the template type and call the object?
I have no idea why I was stuck on this problem for so long. I can specify anything I want in the transform and I even do in my own example lol. I am still curious if there is a way to make your type work with to!MyCustomType(source)
`to` uses natural hints that it can find via introspection. As others have pointed out, you can define a constructor in the target type to take the source type. To go the other way, you can define an `opCast` in the source type (if that's possible). If you want to convert to string (a specialized case), use a `toString` member function. For class to class conversion, `to` will try a dynamic cast if none of the above is the case. I believe there is no specific hook aside from these that allows you to define a conversion path. -Steve
Jun 20 2022