November 20, 2005 Suggestion: Templated polymorphic functions | ||||
---|---|---|---|---|
| ||||
Hi, Contrary to how the subject may sound, this is a suggestion for a small change in implicit template parameters. The spec says: "If a template has exactly one member in it, and the name of that member is the same as the template name, that member is assumed to be referred to in a template instantiation" I suggest an addition. Something like: "If a template only has function members, all of which have the same name as the template, those are assumed to be referred to in a template instantiation." Consider the following (nonsense) template defining a bunch of polymorphic functions: # template foo(T) { # T foo(int x) { return 1; } # T foo(double x) { return 2; } # } Those functions would then be accessed with eg. foo!(int). Eg: foo!(int)(5) returns 1, foo!(int)(1.0) returns 2. --- The reason I bumped into this was trying to implement array conversion functions: # template conv(S:S[],D:D[]) { # D[] conv(S[] src) { # D[] dst; # dst.length = src.length; # foreach(int i, S s; src) # dst[i] = cast(D) s; # return dst; # } # } And then using a "templated typedef" for all basic types: # template to(D:D[]) { # alias conv!(int[],D[]) to; # alias conv!(double[],D[]) to; # // etc... # } Allowing: # const double[] x = [1.5,2.5,-0.9]; # int[] y = to!(int[])(x); // Doesn't compile. Needs to!(int[]).to(x); (Ideally, I would like the syntax x.to!(int[]) to work, but this doesn't work at all for templated functions. I may attend to this in a separate post.) --- Concerning Implicit Template Properties: I'm feeling slightly uncomfortable with the rule that removes the extra scope level when the template and a single parameter has the same name. Wouldn't it be better instead to make this explicit using the 'this' keyword: # template something(T) { # T this(int x) {return 5;} # } # template SomethingElse(T) { # class this { # T x,y; # } # } --- Comments? /Oskar |
November 22, 2005 Re: Suggestion: Templated polymorphic functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Oskar Linde | Oskar Linde wrote: > Hi, > > Contrary to how the subject may sound, this is a suggestion for a small change > in implicit template parameters. The spec says: > > "If a template has exactly one member in it, and the name of that member is the > same as the template name, that member is assumed to be referred to in a > template instantiation" > > I suggest an addition. Something like: > > "If a template only has function members, all of which have the same name as the > template, those are assumed to be referred to in a template instantiation." > > Consider the following (nonsense) template defining a bunch of polymorphic > functions: > > # template foo(T) { > # T foo(int x) { return 1; } > # T foo(double x) { return 2; } > # } > > Those functions would then be accessed with eg. foo!(int). Eg: > foo!(int)(5) returns 1, foo!(int)(1.0) returns 2. That makes sense, but be aware that right now, even this doesn't work: template foo(T) { static if (1) { T foo(int x) { return 1; } } } int x = foo!(int)(5); // No, must use foo!(int).foo(5); Walters indicated he's probably going to change this. But I hope that it would still work, even in extreme cases like: template foo(T) { static if (is (T : int) ) { int foo(int x) { return 1; } } else { struct foo { T s; } } } And if that worked, your suggestion might work too. > Concerning Implicit Template Properties: > > I'm feeling slightly uncomfortable with the rule that removes the extra scope > level when the template and a single parameter has the same name. Wouldn't it > be better instead to make this explicit using the 'this' keyword: > > # template something(T) { > # T this(int x) {return 5;} > # } > > # template SomethingElse(T) { > # class this { > # T x,y; > # } > # } I definitely like the idea -- but does it work? What happens when you need to use the 'this' pointer? How do you distinguish between the class and the instance? class this { this() {} this somefunc(this a) { this = a; return a.b==1 ? this : new this; } } Another possibility might be to use the return keyword at the start of the declaration. I would definitely be interested in something like one of these, if it was possible to prevent it from automatically triggering in template alias parameters (and if there was a way of triggering it later). template t(alias a) { void f() { writefln(typeid(a).typeof); } } template s(Z) { Z s(int q) { return 1; } } t!(s!(int)) ---> a is s!(int).s(), but I want it to pass s!(int) and later I want to invoke s!(int).s(3) I just feel that at the moment, some aspects of the language are too incomplete for the implicit template properties to really work well, right now it can be more of a nuisance. |
Copyright © 1999-2021 by the D Language Foundation