Re: Template method and type resolution of return type
On Sunday, 20 April 2014 at 00:55:31 UTC, David Held wrote: On 4/19/2014 3:31 PM, Andrej Mitrovic via Digitalmars-d-learn wrote: [...] struct S { int get() { return 0; } T get(T)() { return T.init; } } void main() { S s; float x = s.get(); // which overload? (currently int get()) } Isn't this just because concrete methods are better overload candidates than method templates? Dave struct S { ubyte get() { return 0 ; } float get() { return 0.; } } void main() { S s; float x = s.get(); // does'nt know which overload, does'nt compile. }
Re: Template method and type resolution of return type
On Sunday, 20 April 2014 at 07:52:08 UTC, matovitch wrote: struct S { ubyte get() { return 0 ; } float get() { return 0.; } } void main() { S s; float x = s.get(); // does'nt know which overload, does'nt compile. } What I do find interesting though, is that you are allowed to write the overload, whereas C++ would outright block you for ambiguity at the source. This means that with proper meta magic eg `__traits(getOverloadSet, S, get)`, you could, *manually* resolve the ambiguity yourself.
Re: Template method and type resolution of return type
On Sunday, 20 April 2014 at 08:28:07 UTC, monarch_dodra wrote: On Sunday, 20 April 2014 at 07:52:08 UTC, matovitch wrote: struct S { ubyte get() { return 0 ; } float get() { return 0.; } } void main() { S s; float x = s.get(); // does'nt know which overload, does'nt compile. } What I do find interesting though, is that you are allowed to write the overload, whereas C++ would outright block you for ambiguity at the source. This means that with proper meta magic eg `__traits(getOverloadSet, S, get)`, you could, *manually* resolve the ambiguity yourself. You mean getOverloads ? (yes it's interesting) How about this : class S { public { this() {} union other { SFloat u_float; SUbyte u_ubyte; } alias other this; } } struct SFloat { float data; alias data this; } struct SUbyte { ubyte data; alias data this; } void main() { S s; s.other.u_float.data = 0.5; //float x = s; } This gives : main.d(31): Error: need 'this' for 'data' of type 'float'
Template method and type resolution of return type
Hi everyone ! Let's say I have a struct : struct Test { immutable (ubyte)[] data; T get(T)() { return *(cast(T*)((data[0]))); } } This code will work : import std.stdio; void main() { Test t; t.data = [152, 32, 64, 28, 95]; float b = t.get!float; writefln(%s, b); } This won't compile : import std.stdio; void main() { Test t; t.data = [152, 32, 64, 28, 95]; float b = t.get; writefln(%s, b); } This neither: import std.stdio; void main() { Test t; t.data = [152, 32, 64, 28, 95]; float b = t.get!(typeof(b)); writefln(%s, b); } And this will work: import std.stdio; void main() { Test t; t.data = [152, 32, 64, 28, 95]; float b; b = t.get!(typeof(b)); writefln(%s, b); } Why can't dmd infere the type 'float' ? In fact this would allow a nicer syntax for the Json struct in vibe.d for example.
Re: Template method and type resolution of return type
matovitch: struct Test { immutable (ubyte)[] data; T get(T)() { return *(cast(T*)((data[0]))); } It's better to return const/immutable data. Otherwise the program gives undefined results. In alternative use mutable ubytes for data. Also data[0] is probably data.ptr. This won't compile : import std.stdio; void main() { Test t; t.data = [152, 32, 64, 28, 95]; float b = t.get; writefln(%s, b); D doesn't perform inference on the return type. This neither: ... Test t; t.data = [152, 32, 64, 28, 95]; float b = t.get!(typeof(b)); writefln(%s, b); I don't know. Perhaps b is not yet defined. This in theory could work. In fact this would allow a nicer syntax for the Json struct in vibe.d for example. I don't think in future D will behave differently on this code. Bye, bearophile
Re: Template method and type resolution of return type
On Saturday, 19 April 2014 at 17:49:54 UTC, bearophile wrote: matovitch: struct Test { immutable (ubyte)[] data; T get(T)() { return *(cast(T*)((data[0]))); } It's better to return const/immutable data. Otherwise the program gives undefined results. In alternative use mutable ubytes for data. Also data[0] is probably data.ptr. I did'nt know that one. This won't compile : import std.stdio; void main() { Test t; t.data = [152, 32, 64, 28, 95]; float b = t.get; writefln(%s, b); D doesn't perform inference on the return type. I see. But why ? It's seems it exits a workaround overloading cast operators in c++ : http://programmaticallyspeaking.blogspot.se/2012/09/infer-return-type-for-templated.html However I think it would only work with opImplicitCast in D. The code given in vibe.d doc could became : void manipulateJson(Json j) { j = Json.emptyObject; j.name = Example; j.id = 1; // retrieving the values is done using get() assert(j[name] == Example); assert(j[id] == 1); // print out as JSON: {name: Example, id: 1} writefln(JSON: %s, j.toString()); } ps : Thank you for all your great examples on Rosetta code (or the last one about the rubik's cube).
Re: Template method and type resolution of return type
On Saturday, 19 April 2014 at 18:46:28 UTC, matovitch wrote: On Saturday, 19 April 2014 at 17:49:54 UTC, bearophile wrote: matovitch: I did'nt know that one. This last sentence is misleading, let be clear : I know almost nothing when it comes to D...but I'm willing to learn ! ;-)
Re: Template method and type resolution of return type
On Saturday, 19 April 2014 at 18:46:28 UTC, matovitch wrote: On Saturday, 19 April 2014 at 17:49:54 UTC, bearophile wrote: matovitch: struct Test { immutable (ubyte)[] data; T get(T)() { return *(cast(T*)((data[0]))); } It's better to return const/immutable data. Otherwise the program gives undefined results. In alternative use mutable ubytes for data. Also data[0] is probably data.ptr. I did'nt know that one. This won't compile : import std.stdio; void main() { Test t; t.data = [152, 32, 64, 28, 95]; float b = t.get; writefln(%s, b); D doesn't perform inference on the return type. I see. But why ? It's seems it exits a workaround overloading cast operators in c++ : http://programmaticallyspeaking.blogspot.se/2012/09/infer-return-type-for-templated.html However I think it would only work with opImplicitCast in D. The code given in vibe.d doc could became : void manipulateJson(Json j) { j = Json.emptyObject; j.name = Example; j.id = 1; // retrieving the values is done using get() assert(j[name] == Example); assert(j[id] == 1); // print out as JSON: {name: Example, id: 1} writefln(JSON: %s, j.toString()); } ps : Thank you for all your great examples on Rosetta code (or the last one about the rubik's cube). Or even : void manipulateJson(Json j) { j = Json.emptyObject; j.name = Example; j.id = 1; assert(j.name == Example); assert(j.id == 1); // print out as JSON: {name: Example, id: 1} writefln(JSON: %s, j.toString()); } Or at least this will work : void manipulateJson(Json j) { j = Json.emptyObject; j.name = Example; j.id = 1; string s = j.name; assert(s == Example); // print out as JSON: {name: Example, id: 1} writefln(JSON: %s, j.toString()); } Ok I stop fooding.
Re: Template method and type resolution of return type
On 4/19/14, matovitch via Digitalmars-d-learn digitalmars-d-learn@puremagic.com wrote: This won't compile : import std.stdio; void main() { Test t; t.data = [152, 32, 64, 28, 95]; float b = t.get; writefln(%s, b); } Because it's probably overkill. At some point it becomes too much magic. The following currently works but it might be considered an ambiguity with return type inference: - struct S { int get() { return 0; } T get(T)() { return T.init; } } void main() { S s; float x = s.get(); // which overload? (currently int get()) } -
Re: Template method and type resolution of return type
On 4/19/2014 3:31 PM, Andrej Mitrovic via Digitalmars-d-learn wrote: [...] struct S { int get() { return 0; } T get(T)() { return T.init; } } void main() { S s; float x = s.get(); // which overload? (currently int get()) } Isn't this just because concrete methods are better overload candidates than method templates? Dave