Implicit type conversion of an argument when a function is called

John Colvin john.loughran.colvin at gmail.com
Tue Feb 11 05:15:03 PST 2014


On Tuesday, 11 February 2014 at 03:45:30 UTC, Carl Sturtivant 
wrote:
>
> If I define a struct, and I want to pass a string to a function 
> with a parameter of type that very struct, is there any way to 
> arrange that an implicit conversion occurs, assuming a function 
> that maps a string to that struct type exists?
>
> struct data { ........ }
>
> void f( data x) { .... }
>
> void main() {
>     data( "hello"); //convert argument implicitly to type 
> `data`.
> }
>
> It's possible to arrange for such an implicit conversion from 
> an existing type to a newly defined type during assignment, but 
> what about when passing an argument to a function?

With a class you can do this:
class Data
{
	string s;
	this(string s)
	{
		this.s = s;
	}
}

void f(Data x ...)
{
	import std.stdio;
	writeln(x.s);
}

void main()
{
     f("hello"); //convert argument implicitly to type `data`.
}

See Typesafe Variadic Functions at http://dlang.org/function.html

I don't know why you can't do it with a struct.

As a workaround, you can do this:

class Construct(T)
{
	T t;
	this(Q)(Q q)
	{
		static if(is(Q : T))
		{
			t = q;
		}
		else
		{
			this.t = T(q);
		}
	}
}

struct Data
{
	string s;
}

void f(Construct!Data xC ...) //construct the wrapper class
{
	auto x = xC.t; //get the contents.
	
	import std.stdio;
	writeln(x.s);
}

void main()
{
	f("hello");
	f(Data("world"));
}


Overall it's probably best to define f as:

void f(Data x)
{
	import std.stdio;
	writeln(x.s);
}

void f(Construct!Data xC ...)
{
	.f(xC.t);
}

To avoid any overhead when calling normally as well as separating 
the definition of the real function from the concern of automatic 
construction/conversion.


More information about the Digitalmars-d-learn mailing list