Thread overview | ||||||||
---|---|---|---|---|---|---|---|---|
|
February 11, 2014 Implicit type conversion of an argument when a function is called | ||||
---|---|---|---|---|
| ||||
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? |
February 11, 2014 Re: Implicit type conversion of an argument when a function is called | ||||
---|---|---|---|---|
| ||||
Posted in reply to Carl Sturtivant | 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?
Nope, you have to do it explicitly.
f(data("hello"));
You could write a wrapper function do do the conversions for you, but of course, you are still explicitly calling the wrapper at the usage site.
I kinda wish D did have this. The mistake C++ made was having the implicit conversions be the default, not having it be an option. But it isn't in and as far as I know, there are no plans to add it either.
|
February 11, 2014 Re: Implicit type conversion of an argument when a function is called | ||||
---|---|---|---|---|
| ||||
Posted in reply to Carl Sturtivant | 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. |
February 11, 2014 Re: Implicit type conversion of an argument when a function is called | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adam D. Ruppe | On Tuesday, 11 February 2014 at 03:50:16 UTC, Adam D. Ruppe wrote: > 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? > > Nope, you have to do it explicitly. > > f(data("hello")); [...] > I kinda wish D did have this. The mistake C++ made was having the implicit conversions be the default, not having it be an option. But it isn't in and as far as I know, there are no plans to add it either. Disappointing. It could be kept decoupled from constructors and assignment defined conversions by having an analogue of opAssign that's solely for argument passing. |
February 11, 2014 Re: Implicit type conversion of an argument when a function is called | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Colvin | > 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.
Nice technique, I'll remember that. Presumably this can't be extended to functions with more than one Data parameter.
What a curious corner of the language! I am somewhat mystified as to the reasoning/intuition behind the presence of this feature for classes (and not structs). Anybody?
|
February 11, 2014 Re: Implicit type conversion of an argument when a function is called | ||||
---|---|---|---|---|
| ||||
Posted in reply to Carl Sturtivant | On Tuesday, 11 February 2014 at 14:47:31 UTC, Carl Sturtivant wrote:
>> 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.
>
> Nice technique, I'll remember that. Presumably this can't be extended to functions with more than one Data parameter.
You are correct, although you can of course just create a normal D-style variadic function overload that does any conversions necessary and then forwards to the original function, but you get less of a helping hand from the language. In general it's harder as you could have multiple constructors that take different numbers of arguments. My example above should work for any number of args, but if you restrict yourself to 1 to 1 conversions:
void g(A a, B b) {}
void g(TL ...)(TL args)
if(TL.length == 2)
{
//do conversions if possible and pass the converted args to
//g(A,B).
}
In all of this I haven't taken any care over ref-ness. In order to get that correct you likely need to use auto ref and maybe std.algorithm.forward, I haven't thought much about it.
|
Copyright © 1999-2021 by the D Language Foundation