Thread overview
std.conv.to
Jun 17
harakim
Jun 17
harakim
Jun 17
bauss
Jun 17
harakim
June 17

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:

	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?

June 17

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:

	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)

June 17

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:

	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:

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);
}
June 17

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?

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

June 17

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:

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.

June 17
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

June 18

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!

   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?

   auto zar = "123".to!Foo;
   auto bar = to!(Foo)("123");
   auto foo = to!Foo("123"); // <-- this line is bubble

SDB@79

June 20

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:

    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