digitalmars.D.learn - Template function specialization doesn't work
- IGotD- (21/21) Jul 07 2020 I have two template functions
- IGotD- (10/11) Jul 07 2020 I also forgot to mention that the overloadedFunction is used in a
- Steven Schveighoffer (5/33) Jul 07 2020 That specialization is... odd. It's basically saying, is T an array of T...
- Steven Schveighoffer (3/4) Jul 07 2020 Ugh... (T: U[], U)(ref T s)
- IGotD- (9/13) Jul 07 2020 Thank you, that worked and now it picked the correct overloaded
- IGotD- (5/13) Jul 07 2020 Here (T : T[]) is even the example with the correct double[] type
- Steven Schveighoffer (13/32) Jul 07 2020 That's not IFTI, that's template instantiation.
- =?UTF-8?Q?Ali_=c3=87ehreli?= (12/19) Jul 07 2020 There is also template constraints which may be useful:
I have two template functions void overloadedFunction(T)(ref T val) { ... } void overloadedFunction(T : T[])(ref T[] s) { ... } Obviously the second should be used when the parameter is a slice of any type, and the first should be used in other cases. However this doesn't happen, the compiler always picks the first function regardless if the parameter is a slice or not. So ubyte[3] ar = [ 1, 2, 3 ]; ubyte[] arSlice = ar; overloadedFunction(arSlice); The first function will be used. Shouldn't the template argument (T : T[]) make the compiler pick the second one?
Jul 07 2020
On Tuesday, 7 July 2020 at 19:53:30 UTC, IGotD- wrote:...I also forgot to mention that the overloadedFunction is used in a variadic template function. void processAll(T...)(ref T t) { foreach(ref v; t) { overloadedFunction(v); } }
Jul 07 2020
On 7/7/20 3:53 PM, IGotD- wrote:I have two template functions void overloadedFunction(T)(ref T val) { .... } void overloadedFunction(T : T[])(ref T[] s) { .... } Obviously the second should be used when the parameter is a slice of any type, and the first should be used in other cases. However this doesn't happen, the compiler always picks the first function regardless if the parameter is a slice or not. So ubyte[3] ar = [ 1, 2, 3 ]; ubyte[] arSlice = ar; overloadedFunction(arSlice); The first function will be used. Shouldn't the template argument (T : T[]) make the compiler pick the second one?That specialization is... odd. It's basically saying, is T an array of T. I know I've seen this before, so I think it's valid. But maybe not? Have you tried (T: U[], U)(ref T[] s) ? -Steve
Jul 07 2020
On 7/7/20 4:04 PM, Steven Schveighoffer wrote:Have you tried (T: U[], U)(ref T[] s) ?Ugh... (T: U[], U)(ref T s) -Steve
Jul 07 2020
On Tuesday, 7 July 2020 at 20:05:37 UTC, Steven Schveighoffer wrote:On 7/7/20 4:04 PM, Steven Schveighoffer wrote:Thank you, that worked and now it picked the correct overloaded function. I don't understand why and it is a bit counter intuitive. Why two template arguments as I'm not even us using U? If you look at the article https://dlang.org/articles/templates-revisited.html#specialization Then it mentioned that (T : T*) would work. Intuitively, then you would think (T : T[]) would work.Have you tried (T: U[], U)(ref T[] s) ?Ugh... (T: U[], U)(ref T s) -Steve
Jul 07 2020
On Tuesday, 7 July 2020 at 20:14:19 UTC, IGotD- wrote:Thank you, that worked and now it picked the correct overloaded function. I don't understand why and it is a bit counter intuitive. Why two template arguments as I'm not even us using U? If you look at the article https://dlang.org/articles/templates-revisited.html#specialization Then it mentioned that (T : T*) would work. Intuitively, then you would think (T : T[]) would work.Here (T : T[]) is even the example with the correct double[] type as a correct example as well. https://dlang.org/spec/template.html#parameters_specialization I'm confused.
Jul 07 2020
On 7/7/20 4:21 PM, IGotD- wrote:On Tuesday, 7 July 2020 at 20:14:19 UTC, IGotD- wrote:That's not IFTI, that's template instantiation. I bet if you did: overloadedFunction!(ubyte[])(arSlice) it would pick the second one. there is some extra magic going on for IFTI, and I'm not sure how it figures out what to do. I would agree with you that if explicit templates use that rule, so should IFTI. But perhaps there's a good reason why it can't be done. So possibly: overloadedFunction(arSlice) => Pattern match `ref T[]` to `ubyte[]` => T is ubyte => Check ubyte for T : T[], no match. -SteveThank you, that worked and now it picked the correct overloaded function. I don't understand why and it is a bit counter intuitive. Why two template arguments as I'm not even us using U? If you look at the article https://dlang.org/articles/templates-revisited.html#specialization Then it mentioned that (T : T*) would work. Intuitively, then you would think (T : T[]) would work.Here (T : T[]) is even the example with the correct double[] type as a correct example as well. https://dlang.org/spec/template.html#parameters_specialization I'm confused.
Jul 07 2020
On 7/7/20 12:53 PM, IGotD- wrote:ubyte[3] ar = [ 1, 2, 3 ]; ubyte[] arSlice = ar; overloadedFunction(arSlice); The first function will be used. Shouldn't the template argument (T : T[]) make the compiler pick the second one?There is also template constraints which may be useful: import std.traits; void overloadedFunction(T)(ref T val) if (!isArray!T) { writeln("general"); } void overloadedFunction(T)(ref T s) if (isArray!T) { writeln("T[]"); } Ali
Jul 07 2020