digitalmars.D.learn - Template specialization
- Darrell Gallion (5/5) Jan 21 2016 How do you create a template that accepts many types.
- H. S. Teoh via Digitalmars-d-learn (10/15) Jan 21 2016 [...]
- =?UTF-8?Q?Ali_=c3=87ehreli?= (31/36) Jan 21 2016 The straightforward approach is tricky because the ': int' syntax means
- Darrell Gallion (25/63) Jan 21 2016 I must apologize for such a vague question. Frustration had me.
- Marc =?UTF-8?B?U2Now7x0eg==?= (4/26) Jan 22 2016 Have a look at the first template constraint. It checks whether
- Darrell Gallion (15/47) Jan 22 2016 I'm aware this doesn't look right or compile.
- Darrell Gallion (28/76) Jan 22 2016 What was getting me...
- =?UTF-8?Q?Ali_=c3=87ehreli?= (4/5) Jan 22 2016 Reported:
- Marc =?UTF-8?B?U2Now7x0eg==?= (4/52) Jan 22 2016 Just remove the `!` in the first template constraint, and it will
How do you create a template that accepts many types. But overrides just one of them? Don't want to write out all of the specializations. Hours of google and I'm sure it's simple... -=Darrell
Jan 21 2016
On Thu, Jan 21, 2016 at 11:37:34PM +0000, Darrell Gallion via Digitalmars-d-learn wrote:How do you create a template that accepts many types. But overrides just one of them? Don't want to write out all of the specializations. Hours of google and I'm sure it's simple...[...] I'm afraid your question is a little too ambiguous. Could you rephrase what it is you're trying to accomplish? Maybe with some code snippet that you want to work but currently doesn't? I'm not sure I understand why you have to write out any of the specializations at all... or what you mean by "override". T -- It always amuses me that Windows has a Safe Mode during bootup. Does that mean that Windows is normally unsafe?
Jan 21 2016
On 01/21/2016 03:37 PM, Darrell Gallion wrote:How do you create a template that accepts many types. But overrides just one of them? Don't want to write out all of the specializations. Hours of google and I'm sure it's simple... -=DarrellThe straightforward approach is tricky because the ': int' syntax means "is implicitly convertible"; so, even the case where B is 'char' would be bound to the specialization: void foo(A, B, C)() { pragma(msg, "general"); } void foo(A, B : int, C)() { // <-- 'B : int' specialization pragma(msg, "special"); } void main() { foo!(char, string, double)(); foo!(short, int, float)(); } A better approach is using template constraints: void foo(A, B, C)() if (!is (B == int)) { // <-- 'B != int' pragma(msg, "general"); } void foo(A, B, C)() if (is (B == int)) { // <-- 'B == int' pragma(msg, "special"); } void main() { foo!(char, string, double)(); foo!(short, int, float)(); } But that has its own problem of needing to reverse the logic for the general case (and other cases), which may become very complicated to write (or to get right) in some cases. Ali
Jan 21 2016
On Friday, 22 January 2016 at 00:08:56 UTC, Ali Çehreli wrote:On 01/21/2016 03:37 PM, Darrell Gallion wrote:I must apologize for such a vague question. Frustration had me. import std.stdio; void foo(A)() if (!is (A == int)) { pragma(msg, "int"); } void foo(A)() if (is (A == int[])) { pragma(msg, "int[]"); } void main() { foo!(int)(); foo!(int[])(); } =========== source\app.d(15): Error: template app.foo cannot deduce function from argument types !(int)(), candidates are: source\app.d(3): app.foo(A)() if (!is(A == int)) source\app.d(8): app.foo(A)() if (is(A == int[])) source\app.d(16): Error: app.foo called with argument types () matches both: source\app.d(3): app.foo!(int[]).foo() and: source\app.d(8): app.foo!(int[]).foo()How do you create a template that accepts many types. But overrides just one of them? Don't want to write out all of the specializations. Hours of google and I'm sure it's simple... -=DarrellThe straightforward approach is tricky because the ': int' syntax means "is implicitly convertible"; so, even the case where B is 'char' would be bound to the specialization: void foo(A, B, C)() { pragma(msg, "general"); } void foo(A, B : int, C)() { // <-- 'B : int' specialization pragma(msg, "special"); } void main() { foo!(char, string, double)(); foo!(short, int, float)(); } A better approach is using template constraints: void foo(A, B, C)() if (!is (B == int)) { // <-- 'B != int' pragma(msg, "general"); } void foo(A, B, C)() if (is (B == int)) { // <-- 'B == int' pragma(msg, "special"); } void main() { foo!(char, string, double)(); foo!(short, int, float)(); } But that has its own problem of needing to reverse the logic for the general case (and other cases), which may become very complicated to write (or to get right) in some cases. Ali
Jan 21 2016
On Friday, 22 January 2016 at 01:33:42 UTC, Darrell Gallion wrote:void foo(A)() if (!is (A == int)) { pragma(msg, "int"); } void foo(A)() if (is (A == int[])) { pragma(msg, "int[]"); } void main() { foo!(int)(); foo!(int[])(); } =========== source\app.d(15): Error: template app.foo cannot deduce function from argument types !(int)(), candidates are: source\app.d(3): app.foo(A)() if (!is(A == int)) source\app.d(8): app.foo(A)() if (is(A == int[])) source\app.d(16): Error: app.foo called with argument types () matches both: source\app.d(3): app.foo!(int[]).foo() and: source\app.d(8): app.foo!(int[]).foo()Have a look at the first template constraint. It checks whether the template parameter _is not_ `int`, so of course, the first instantiation fails, and the second one is ambiguous.
Jan 22 2016
On Friday, 22 January 2016 at 11:23:56 UTC, Marc Schütz wrote:On Friday, 22 January 2016 at 01:33:42 UTC, Darrell Gallion wrote:I'm aware this doesn't look right or compile. How do I do this? void foo(int x) { } void foo(int [] x) { } template foo(T)(T x){} void main() { int x; int [] a; foo((x); foo(a); foo("hi"); }void foo(A)() if (!is (A == int)) { pragma(msg, "int"); } void foo(A)() if (is (A == int[])) { pragma(msg, "int[]"); } void main() { foo!(int)(); foo!(int[])(); } =========== source\app.d(15): Error: template app.foo cannot deduce function from argument types !(int)(), candidates are: source\app.d(3): app.foo(A)() if (!is(A == int)) source\app.d(8): app.foo(A)() if (is(A == int[])) source\app.d(16): Error: app.foo called with argument types () matches both: source\app.d(3): app.foo!(int[]).foo() and: source\app.d(8): app.foo!(int[]).foo()Have a look at the first template constraint. It checks whether the template parameter _is not_ `int`, so of course, the first instantiation fails, and the second one is ambiguous.
Jan 22 2016
On Friday, 22 January 2016 at 13:03:52 UTC, Darrell Gallion wrote:On Friday, 22 January 2016 at 11:23:56 UTC, Marc Schütz wrote:What was getting me... Defining the templates within another function, fails. void main(){ long foo(T: int)(T t) { return cast(long)t; } long[] foo(T: int[])(T t) { long [] ar; return ar; } T foo(T)(T t) { return t; } foo(1); foo([1,2]); foo("hi"); } source/app.d(224,3): Error: declaration foo(T : int[])(T t) is already defined source/app.d(229,3): Error: declaration foo(T)(T t) is already defined source/app.d(236,6): Error: template D main.foo cannot deduce function from argument types !()(int[]), candidates are: source/app.d(219,8): app.main.foo(T : int)(T t) source/app.d(237,6): Error: template D main.foo cannot deduce function from argument types !()(string), candidates are: source/app.d(219,8): app.main.foo(T : int)(T t)On Friday, 22 January 2016 at 01:33:42 UTC, Darrell Gallion wrote:I'm aware this doesn't look right or compile. How do I do this? void foo(int x) { } void foo(int [] x) { } template foo(T)(T x){} void main() { int x; int [] a; foo((x); foo(a); foo("hi"); }void foo(A)() if (!is (A == int)) { pragma(msg, "int"); } void foo(A)() if (is (A == int[])) { pragma(msg, "int[]"); } void main() { foo!(int)(); foo!(int[])(); } =========== source\app.d(15): Error: template app.foo cannot deduce function from argument types !(int)(), candidates are: source\app.d(3): app.foo(A)() if (!is(A == int)) source\app.d(8): app.foo(A)() if (is(A == int[])) source\app.d(16): Error: app.foo called with argument types () matches both: source\app.d(3): app.foo!(int[]).foo() and: source\app.d(8): app.foo!(int[]).foo()Have a look at the first template constraint. It checks whether the template parameter _is not_ `int`, so of course, the first instantiation fails, and the second one is ambiguous.
Jan 22 2016
On 01/22/2016 07:41 AM, Darrell Gallion wrote:Defining the template [specializations] within another function, fails.Reported: https://issues.dlang.org/show_bug.cgi?id=15592 Ali
Jan 22 2016
On Friday, 22 January 2016 at 13:03:52 UTC, Darrell Gallion wrote:On Friday, 22 January 2016 at 11:23:56 UTC, Marc Schütz wrote:Just remove the `!` in the first template constraint, and it will compile.On Friday, 22 January 2016 at 01:33:42 UTC, Darrell Gallion wrote:I'm aware this doesn't look right or compile. How do I do this?void foo(A)() if (!is (A == int)) { pragma(msg, "int"); } void foo(A)() if (is (A == int[])) { pragma(msg, "int[]"); } void main() { foo!(int)(); foo!(int[])(); } =========== source\app.d(15): Error: template app.foo cannot deduce function from argument types !(int)(), candidates are: source\app.d(3): app.foo(A)() if (!is(A == int)) source\app.d(8): app.foo(A)() if (is(A == int[])) source\app.d(16): Error: app.foo called with argument types () matches both: source\app.d(3): app.foo!(int[]).foo() and: source\app.d(8): app.foo!(int[]).foo()Have a look at the first template constraint. It checks whether the template parameter _is not_ `int`, so of course, the first instantiation fails, and the second one is ambiguous.void foo(int x) { } void foo(int [] x) { } template foo(T)(T x){} void main() { int x; int [] a; foo((x); foo(a); foo("hi"); }You lost me here...
Jan 22 2016