digitalmars.D.learn - Template argument deduction not working with template specialization
- Paul (11/22) Jan 17 2021 While trying to use template specializations I noticed the
- Steven Schveighoffer (6/32) Jan 17 2021 I've always hated that aspect of specialization. I don't really
- Paul (5/9) Jan 17 2021 I totally agree with that, that confuses me as well.
- Steven Schveighoffer (5/12) Jan 17 2021 It's basically saying if T matches the pattern U[] for some U (which is
- Paul (17/36) Jan 17 2021 I just figured out half of my frustration is caused by a
While trying to use template specializations I noticed the argument deductions do not yield the same version as the ones yielded when being explicit. Example:uint a = 1; uint[] b = [2]; TFoo(a); TFoo!(uint[])(b);void TFoo(T)(T a) { pragma(msg, "T: " ~ T.stringof); } void TFoo(T : T[])(T[] a) { pragma(msg, "T[]: " ~ T.stringof); }I noticed that an automatically deduced TFoo call always yields the first, while TFoo!(uint[]) yields the array version if present, and defaults to the first elsewise. Am I incorrect in expecting the same behavior when (ab)using argument deduction or does my usage make sense? I tried searching for this combination (deduction & specialization) but couldn't find another forum post / documentation example.
Jan 17 2021
On 1/17/21 11:22 AM, Paul wrote:While trying to use template specializations I noticed the argument deductions do not yield the same version as the ones yielded when being explicit. Example:I've always hated that aspect of specialization. I don't really understand why it's valid (how can T be T[]?) This works: void TFoo(T : U[], U)(T a) -Steveuint a = 1; uint[] b = [2]; TFoo(a); TFoo!(uint[])(b);void TFoo(T)(T a) { pragma(msg, "T: " ~ T.stringof); } void TFoo(T : T[])(T[] a) { pragma(msg, "T[]: " ~ T.stringof); }I noticed that an automatically deduced TFoo call always yields the first, while TFoo!(uint[]) yields the array version if present, and defaults to the first elsewise. Am I incorrect in expecting the same behavior when (ab)using argument deduction or does my usage make sense? I tried searching for this combination (deduction & specialization) but couldn't find another forum post / documentation example.
Jan 17 2021
On Sunday, 17 January 2021 at 16:42:27 UTC, Steven Schveighoffer wrote:I've always hated that aspect of specialization. I don't really understand why it's valid (how can T be T[]?)I totally agree with that, that confuses me as well.This works: void TFoo(T : U[], U)(T a)Oh cool, that's surprising to say the least. Thanks! This indeed works with argument deduction :)
Jan 17 2021
On 1/17/21 3:41 PM, Paul wrote:On Sunday, 17 January 2021 at 16:42:27 UTC, Steven Schveighoffer wrote:It's basically saying if T matches the pattern U[] for some U (which is actually defined now inside the function), then it's a match (and preferred over the non-specialized template). -SteveThis works: void TFoo(T : U[], U)(T a)Oh cool, that's surprising to say the least. Thanks! This indeed works with argument deduction :)
Jan 17 2021
I just figured out half of my frustration is caused by a collision between the 'alias this'd template possibillity and the normal one. For example:struct Bar(uint size, V) { V[size] blup; alias blup this; } void foo(S : T[], T)(S a) { pragma(msg, "first"); } void foo(S : Bar!(T, U), uint T, U)(S a) { pragma(msg, "second"); }Bar!(2, int) bar; foo(bar);Will cause "called with argument types `(Bar!(2u, int))` matches both:DUB" (And "undefined identifier `T`DUB", "undefined identifier `U`DUB", but thats a false positive :/) While removal of either will make it work fine, as would removal of the alias. Templating:The template picked to instantiate is the one that is most specialized that fits the types of the TemplateArgumentList.Alias this:If an aggregate declaration defines an opCmp or opEquals method, it will take precedence to that of the aliased this member.I was of the impression D only defaulted to the alias when the original implementation of a (member) function was missing / disfunctional. Shouldn't aliasing also follow this logic when using template specializations? (Even though it may not be a member function)
Jan 17 2021