digitalmars.D.learn - Deducing a template retrun parameter type based on an assignment?
- Jeremy DeHaan (14/14) Jan 29 2015 I have a template fuction that looks like this:
- Vlad Levenfeld (14/28) Jan 29 2015 for template type deduction to work, you have to supply an
- Jeremy DeHaan (12/29) Jan 29 2015 That seems strange. I figured that it would be smart enough to
- Vlad Levenfeld (14/24) Jan 29 2015 It seems sensible to me, as changing string to auto would leave
- bearophile (5/8) Jan 30 2015 For that you need languages like Haskell/Rust. D type inference
- "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> (9/15) Jan 30 2015 But it could, right (for arguments and return expressions, too)?
- Steven Schveighoffer (15/30) Jan 30 2015 Walter made a conscious decision not to depend on return types for
I have a template fuction that looks like this: immutable(T)[] getString(T)() const if (is(T == dchar)||is(T == wchar)||is(T == char)) Basically, I was hoping that the type would be deduced based on the prameter that was being assigned to like so. string ret = thing.getString(); Apparently that does not work, though. I get informed that the type of the template is not able to be deduced. I'm curious as to why it was not able to deduce it on its own. Additionally, and I haven't run my code to try this yet, but giving T a default type compiled to my surprise. immutable(T)[] getString(T=char)() const if (is(T == dchar)||is(T == wchar)||is(T == char)) Is something like this supposed even to work?
Jan 29 2015
On Friday, 30 January 2015 at 06:35:31 UTC, Jeremy DeHaan wrote:I have a template fuction that looks like this: immutable(T)[] getString(T)() const if (is(T == dchar)||is(T == wchar)||is(T == char)) Basically, I was hoping that the type would be deduced based on the prameter that was being assigned to like so. string ret = thing.getString(); Apparently that does not work, though. I get informed that the type of the template is not able to be deduced. I'm curious as to why it was not able to deduce it on its own. Additionally, and I haven't run my code to try this yet, but giving T a default type compiled to my surprise. immutable(T)[] getString(T=char)() const if (is(T == dchar)||is(T == wchar)||is(T == char)) Is something like this supposed even to work?for template type deduction to work, you have to supply an argument. Your type signature would need to look like this: immutable(T)[] getString(T)(T arg) const and then T would be deduced from arg. But string ret = thing.getString(); won't compile because it is rewritten to getString(thing), but your getString function takes no runtime parameters. It looks like the signature I wrote earlier is what you actually want. As to your second example, it'll work fine. Basically your signature says "only accept dchar, wchar or char, but if nothing's been specified, default to char". But if you rewrite getString to take one parameter, then the default template arg is redundant.
Jan 29 2015
On Friday, 30 January 2015 at 06:58:58 UTC, Vlad Levenfeld wrote:On Friday, 30 January 2015 at 06:35:31 UTC, Jeremy DeHaan wrote:That seems strange. I figured that it would be smart enough to deduce the parameter type based on the type that it was trying to be assigned to.A bunch of stufffor template type deduction to work, you have to supply an argument. Your type signature would need to look like this: immutable(T)[] getString(T)(T arg) const and then T would be deduced from arg.But string ret = thing.getString(); won't compile because it is rewritten to getString(thing), but your getString function takes no runtime parameters. It looks like the signature I wrote earlier is what you actually want.Whoops. I should have mentioned that this is a member function in a class and not a free fiction. Not that it changes much about the deduction.As to your second example, it'll work fine. Basically your signature says "only accept dchar, wchar or char, but if nothing's been specified, default to char". But if you rewrite getString to take one parameter, then the default template arg is redundant.That is good to hear. It seemed like that was the way it would work, but I've never had to specify a default template parameter type. I'm hoping to avoid having to specify a template parameter, but it seems like it can't be helped if users want to get their string type as a wstring or dstring though.
Jan 29 2015
On Friday, 30 January 2015 at 07:13:09 UTC, Jeremy DeHaan wrote:That seems strange. I figured that it would be smart enough to deduce the parameter type based on the type that it was trying to be assigned to.It seems sensible to me, as changing string to auto would leave the type of the expression undefined. But maybe your expectation is a reasonable enhancement, I'll leave it for someone more knowledgeable than myself to judge.That is good to hear. It seemed like that was the way it would work, but I've never had to specify a default template parameter type. I'm hoping to avoid having to specify a template parameter, but it seems like it can't be helped if users want to get their string type as a wstring or dstring though.It doesn't seem too bad to me. I used a similar pattern quite recently to wrap glGetIntegeriv into gl.get!int. One way or another you'll have to specify the type, but if you want to cut down on redundant code then auto ret = thing.getString!wchar; is a good bet. And I'm fairly certain that since you're using a default param of char, auto ret = thing.getString; should compile and result in ret being a char string.
Jan 29 2015
Jeremy DeHaan:I figured that it would be smart enough to deduce the parameter type based on the type that it was trying to be assigned to.For that you need languages like Haskell/Rust. D type inference doesn't work from the type something is assigned to. Bye, bearophile
Jan 30 2015
On Friday, 30 January 2015 at 08:52:41 UTC, bearophile wrote:Jeremy DeHaan:But it could, right (for arguments and return expressions, too)? At least I don't see any real obstacles. Just file an enhancement request if you think it's worthwhile, or start a discussion on digitalmars.D. Of course, it cannot work for `auto x = getString();` or `foo(getString())` where there are several overloads of `foo()`. The next step would then be overloading on the return type, which is related.I figured that it would be smart enough to deduce the parameter type based on the type that it was trying to be assigned to.For that you need languages like Haskell/Rust. D type inference doesn't work from the type something is assigned to.
Jan 30 2015
On 1/30/15 5:06 AM, "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net>" wrote:On Friday, 30 January 2015 at 08:52:41 UTC, bearophile wrote:Walter made a conscious decision not to depend on return types for overloads or any other deduction. It makes implementation of the language simpler. C++ has tremendously complex rules for overloading because of this. Note, you can easily change this: string x = getString(); to this: auto x = getString!(char)(); which is still DRY. One possible mechanism for working around this for when you already have a variable is to change the return value into a parameter void getStringParam(T)(ref T[] x) if ... { x = getString!(T)(); } -SteveJeremy DeHaan:But it could, right (for arguments and return expressions, too)? At least I don't see any real obstacles. Just file an enhancement request if you think it's worthwhile, or start a discussion on digitalmars.D. Of course, it cannot work for `auto x = getString();` or `foo(getString())` where there are several overloads of `foo()`. The next step would then be overloading on the return type, which is related.I figured that it would be smart enough to deduce the parameter type based on the type that it was trying to be assigned to.For that you need languages like Haskell/Rust. D type inference doesn't work from the type something is assigned to.
Jan 30 2015