digitalmars.D.learn - Template method and type resolution of return type
- matovitch (49/49) Apr 19 2014 Hi everyone !
- bearophile (11/34) Apr 19 2014 It's better to return const/immutable data. Otherwise the program
- matovitch (22/46) Apr 19 2014 I see. But why ?
- Andrej Mitrovic via Digitalmars-d-learn (17/26) Apr 19 2014 Because it's probably overkill. At some point it becomes too much
- David Held (4/15) Apr 19 2014 Isn't this just because concrete methods are better overload candidates
- matovitch (12/30) Apr 20 2014 struct S
- monarch_dodra (7/18) Apr 20 2014 What I do find interesting though, is that you are allowed to
- matovitch (33/53) Apr 20 2014 You mean getOverloads ? (yes it's interesting)
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.
Apr 19 2014
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
Apr 19 2014
On Saturday, 19 April 2014 at 17:49:54 UTC, bearophile wrote:matovitch:I did'nt know that one.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 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).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.
Apr 19 2014
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 ! ;-)
Apr 19 2014
On Saturday, 19 April 2014 at 18:46:28 UTC, matovitch wrote:On Saturday, 19 April 2014 at 17:49:54 UTC, bearophile wrote: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.matovitch:I did'nt know that one.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 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).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.
Apr 19 2014
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()) } -----
Apr 19 2014
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
Apr 19 2014
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 { ubyte get() { return 0 ; } float get() { return 0.; } } void main() { S s; float x = s.get(); // does'nt know which overload, does'nt compile. }[...] 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
Apr 20 2014
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.
Apr 20 2014
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: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'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.
Apr 20 2014