Re: Erroneous "auto can only be used for template function parameters"?
On Saturday, 20 June 2015 at 01:50:11 UTC, Yuxuan Shui wrote: Try to compile this code snippet: import std.traits; template a(R) { auto a(S)(auto ref R i) { return cast(S)i*2; } } template ReturnTypeEx(alias A, B) { alias ReturnTypeEx = ReturnType!(A!B); } template b(alias R) { int b(S)(S i) { alias Ra = ReturnTypeEx!(R, S); return cast(int)R!S(i); } } void main() { alias bb = b!(a!ulong); pragma(msg, ReturnTypeEx!(bb, int)); } DMD reports: sadf.d(3): Error: auto can only be used for template function parameters sadf.d(8): Error: template instance sadf.a!ulong.A!int error instantiating sadf.d(12):instantiated from here: ReturnTypeEx!(a, int) sadf.d(8):instantiated from here: A!int sadf.d(18):instantiated from here: ReturnTypeEx!(b, int) sadf.d(18):while evaluating pragma(msg, ReturnTypeEx!(b, int)) But a(S)(auto ref R) is indeed a template function, so I don't understand. After more experimenting, here's what I got. This time no nested templates are involved, this seems more likely an 'auto ref' bug. import std.traits, std.range; void a(S)(auto ref S i) { } void b(S)(auto ref S i) if (isInputRange!S) { } void c(S)(ref S i) if (isInputRange!S) { } void devil(alias S)() { } void main() { a!string(""); //Works <--- This line affects the result of devil!(a!string) b!string(""); //Works //Next line is weird, it: //1. Err, 'auto ref can only be used with template function', if 'a' is not // instantiated with 'a!string' first //2. Works, if 'a!string' is done first alias x = devil!(a!string); alias xx = devil!(b!string); //Err, template doesn't match alias xxx = devil!(c!string); //Works } I'm using DMD 2.067.1
Re: Erroneous "auto can only be used for template function parameters"?
On Sunday, 21 June 2015 at 02:37:59 UTC, Yuxuan Shui wrote: On Sunday, 21 June 2015 at 01:26:51 UTC, Adam D. Ruppe wrote: On Saturday, 20 June 2015 at 01:50:11 UTC, Yuxuan Shui wrote: auto ref R) is indeed a template function, so I don't understand. But R is not a parameter on the function itself. It comes from the outside template. Move it to the inside template, rewrite it as: auto a(S, R)(auto ref R i) { return cast(S)i*2; } and you should get further. Also the same error persists even if I change 'a' to auto a(S)(auto ref S i) I'm not reproducing in DMD 2.067: void main() { int m; a!int(m); } template a(R) { auto a(S)(auto ref S i) { } } Note that since template 'a' and function template 'a' have the same name you're invoking IFTI, otherwise the code would look like: void main() { int m; z!int.a(m); } template z(R) { auto a(S)(auto ref S i) { } }
Re: Erroneous "auto can only be used for template function parameters"?
On 6/22/15 1:37 PM, Yuxuan Shui wrote: On Monday, 22 June 2015 at 13:49:21 UTC, Steven Schveighoffer wrote: On 6/20/15 10:26 PM, Yuxuan Shui wrote: On Sunday, 21 June 2015 at 01:26:51 UTC, Adam D. Ruppe wrote: On Saturday, 20 June 2015 at 01:50:11 UTC, Yuxuan Shui wrote: auto ref R) is indeed a template function, so I don't understand. But R is not a parameter on the function itself. It comes from the outside template. Move it to the inside template, rewrite it as: auto a(S, R)(auto ref R i) { return cast(S)i*2; } and you should get further. But surely nested template should be able to access outer template's parameter. If you have to instantiate it to see how to instantiate it, it doesn't work. General rule of thumb on templates. IFTI only works at one level. I can't see any IFTI in my code, can you point it out? Sorry, I misunderstood what is happening here. I don't know what the rules are for auto ref for nested template functions, or for explicit instantiation. -Steve
Re: Erroneous "auto can only be used for template function parameters"?
On Monday, 22 June 2015 at 13:49:21 UTC, Steven Schveighoffer wrote: On 6/20/15 10:26 PM, Yuxuan Shui wrote: On Sunday, 21 June 2015 at 01:26:51 UTC, Adam D. Ruppe wrote: On Saturday, 20 June 2015 at 01:50:11 UTC, Yuxuan Shui wrote: auto ref R) is indeed a template function, so I don't understand. But R is not a parameter on the function itself. It comes from the outside template. Move it to the inside template, rewrite it as: auto a(S, R)(auto ref R i) { return cast(S)i*2; } and you should get further. But surely nested template should be able to access outer template's parameter. If you have to instantiate it to see how to instantiate it, it doesn't work. General rule of thumb on templates. IFTI only works at one level. -Steve I can't see any IFTI in my code, can you point it out?
Re: Erroneous "auto can only be used for template function parameters"?
On 6/20/15 10:26 PM, Yuxuan Shui wrote: On Sunday, 21 June 2015 at 01:26:51 UTC, Adam D. Ruppe wrote: On Saturday, 20 June 2015 at 01:50:11 UTC, Yuxuan Shui wrote: auto ref R) is indeed a template function, so I don't understand. But R is not a parameter on the function itself. It comes from the outside template. Move it to the inside template, rewrite it as: auto a(S, R)(auto ref R i) { return cast(S)i*2; } and you should get further. But surely nested template should be able to access outer template's parameter. If you have to instantiate it to see how to instantiate it, it doesn't work. General rule of thumb on templates. IFTI only works at one level. -Steve
Re: Erroneous "auto can only be used for template function parameters"?
On Sunday, 21 June 2015 at 01:26:51 UTC, Adam D. Ruppe wrote: On Saturday, 20 June 2015 at 01:50:11 UTC, Yuxuan Shui wrote: auto ref R) is indeed a template function, so I don't understand. But R is not a parameter on the function itself. It comes from the outside template. Move it to the inside template, rewrite it as: auto a(S, R)(auto ref R i) { return cast(S)i*2; } and you should get further. Also the same error persists even if I change 'a' to auto a(S)(auto ref S i)
Re: Erroneous "auto can only be used for template function parameters"?
On Sunday, 21 June 2015 at 01:26:51 UTC, Adam D. Ruppe wrote: On Saturday, 20 June 2015 at 01:50:11 UTC, Yuxuan Shui wrote: auto ref R) is indeed a template function, so I don't understand. But R is not a parameter on the function itself. It comes from the outside template. Move it to the inside template, rewrite it as: auto a(S, R)(auto ref R i) { return cast(S)i*2; } and you should get further. But surely nested template should be able to access outer template's parameter.
Re: Erroneous "auto can only be used for template function parameters"?
On Saturday, 20 June 2015 at 01:50:11 UTC, Yuxuan Shui wrote: auto ref R) is indeed a template function, so I don't understand. But R is not a parameter on the function itself. It comes from the outside template. Move it to the inside template, rewrite it as: auto a(S, R)(auto ref R i) { return cast(S)i*2; } and you should get further.
Re: Erroneous "auto can only be used for template function parameters"?
On Saturday, 20 June 2015 at 01:50:11 UTC, Yuxuan Shui wrote: Try to compile this code snippet: import std.traits; template a(R) { auto a(S)(auto ref R i) { return cast(S)i*2; } } template ReturnTypeEx(alias A, B) { alias ReturnTypeEx = ReturnType!(A!B); } template b(alias R) { int b(S)(S i) { alias Ra = ReturnTypeEx!(R, S); return cast(int)R!S(i); } } void main() { alias bb = b!(a!ulong); pragma(msg, ReturnTypeEx!(bb, int)); } DMD reports: sadf.d(3): Error: auto can only be used for template function parameters sadf.d(8): Error: template instance sadf.a!ulong.A!int error instantiating sadf.d(12):instantiated from here: ReturnTypeEx!(a, int) sadf.d(8):instantiated from here: A!int sadf.d(18):instantiated from here: ReturnTypeEx!(b, int) sadf.d(18):while evaluating pragma(msg, ReturnTypeEx!(b, int)) But a(S)(auto ref R) is indeed a template function, so I don't understand. Another thing I discovered is instantiation like this: (a!T)!S will result in "C style cast illegal", which is clearly wrong because this is not a cast, (a!T) is not necessarily a type.
Erroneous "auto can only be used for template function parameters"?
Try to compile this code snippet: import std.traits; template a(R) { auto a(S)(auto ref R i) { return cast(S)i*2; } } template ReturnTypeEx(alias A, B) { alias ReturnTypeEx = ReturnType!(A!B); } template b(alias R) { int b(S)(S i) { alias Ra = ReturnTypeEx!(R, S); return cast(int)R!S(i); } } void main() { alias bb = b!(a!ulong); pragma(msg, ReturnTypeEx!(bb, int)); } DMD reports: sadf.d(3): Error: auto can only be used for template function parameters sadf.d(8): Error: template instance sadf.a!ulong.A!int error instantiating sadf.d(12):instantiated from here: ReturnTypeEx!(a, int) sadf.d(8):instantiated from here: A!int sadf.d(18):instantiated from here: ReturnTypeEx!(b, int) sadf.d(18):while evaluating pragma(msg, ReturnTypeEx!(b, int)) But a(S)(auto ref R) is indeed a template function, so I don't understand.