Re: cannot use local f as parameter to non-global template
On Monday, 10 December 2018 at 16:15:36 UTC, aliak wrote: Ah, that's a good way of breaking it down. But ok, so then the other version would be lowered to: template match(handlers...) { template match(T) { auto match(T holder) { return handlers[0](holder); } } } So now the second template is accessing a T, which is actually a Holder!f right? But doing that makes it "work". Even though the number of "contexts" needed to execute "handlers[0](holder)" is the same, right? Holder!f is a type, not a delegate, so passing it as a parameter to a non-global template is fine. Issue 5710 only applies to delegates passed directly as parameters. Trying to reason about the "number of contexts" required is a waste of time. There's no logical, principled reason why one works and the other doesn't. It's purely an artifact of details in the compiler implementation.
Re: cannot use local f as parameter to non-global template
On Saturday, 8 December 2018 at 14:21:01 UTC, Paul Backus wrote: On Saturday, 8 December 2018 at 09:57:29 UTC, aliak wrote: This compiles fine. However, if I change the match template to: template match(handlers...) { auto match(alias f)(Holder!f holder) { return handlers[0](holder); } } Notice the template parameter of the eponymous match is an alias now, and the function parameter is typed as a Holder. The "de-sugared" version of your second `match` function looks like this: template match(handlers...) { template match(alias f) { auto match(Holder!f holder) { return handlers[0](holder); } } } Notice the second template nested inside the first. That's the "non-gloal template" the error is complaining about. Ah, that's a good way of breaking it down. But ok, so then the other version would be lowered to: template match(handlers...) { template match(T) { auto match(T holder) { return handlers[0](holder); } } } So now the second template is accessing a T, which is actually a Holder!f right? But doing that makes it "work". Even though the number of "contexts" needed to execute "handlers[0](holder)" is the same, right?
Re: cannot use local f as parameter to non-global template
On Saturday, 8 December 2018 at 09:57:29 UTC, aliak wrote: This compiles fine. However, if I change the match template to: template match(handlers...) { auto match(alias f)(Holder!f holder) { return handlers[0](holder); } } Notice the template parameter of the eponymous match is an alias now, and the function parameter is typed as a Holder. The "de-sugared" version of your second `match` function looks like this: template match(handlers...) { template match(alias f) { auto match(Holder!f holder) { return handlers[0](holder); } } } Notice the second template nested inside the first. That's the "non-gloal template" the error is complaining about.
cannot use local f as parameter to non-global template
Hi, I'm wondering about why this happens in a certain situation and not another. I have the following code: struct Holder(alias fun) { alias T = typeof(fun()); T get() { return fun(); } alias get this; } template match(handlers...) { auto match(T)(T holder) { return handlers[0](holder); } } void main() { int f() { return i7 } auto value = Holder!f().match!( (int a) => f() ); } This compiles fine. However, if I change the match template to: template match(handlers...) { auto match(alias f)(Holder!f holder) { return handlers[0](holder); } } Notice the template parameter of the eponymous match is an alias now, and the function parameter is typed as a Holder. The error you get is basically because of bug 5710 [0] I guess. But I'm confused as to why the same thing doesn't then happen when using match(T) as opposed to match(alias f)? I can work around it by have a template constraint on match of course. But still curious why one version works and the other not, they both have to access the same frame+context data at the end of the day. [0]: https://issues.dlang.org/show_bug.cgi?id=5710
Re: template instance cannot use local 'f' as parameter to non-global template
Anybody an idea?
Re: template instance cannot use local 'f' as parameter to non-global template
On 12.07.2011 15:06, Trass3r wrote: Is this a bug? If not, how do you make it work? void h() {} class Bla { mixin wrap!h; } mixin template wrap(alias f) { void blub(alias g = f)() { } } void main() { Bla b = new Bla(); b.blub(); } test.d(18): Error: template instance cannot use local 'f' as parameter to non-global template blub(alias g = f) test.d(18): Error: template instance forward reference of f test.d(18): Error: template instance test.Bla.wrap!(h).blub!(f) error instantiating I am not sure but i am not that used to those template aliases anyway.
Re: template instance cannot use local 'f' as parameter to non-global template
On Tue, 12 Jul 2011 09:06:56 -0400, Trass3r u...@known.com wrote: Is this a bug? If not, how do you make it work? void h() {} class Bla { mixin wrap!h; } mixin template wrap(alias f) { void blub(alias g = f)() { } } void main() { Bla b = new Bla(); b.blub(); } test.d(18): Error: template instance cannot use local 'f' as parameter to non-global template blub(alias g = f) test.d(18): Error: template instance forward reference of f test.d(18): Error: template instance test.Bla.wrap!(h).blub!(f) error instantiating I've seen this error before... *searches memory and old code* Here you go: http://d.puremagic.com/issues/show_bug.cgi?id=3051 As a workaround, is there a reason you need blub to be parameterized? I mean, f is already part of the template. -Steve
Re: template instance cannot use local 'f' as parameter to non-global template
Am 13.07.2011, 16:02 Uhr, schrieb Steven Schveighoffer schvei...@yahoo.com: void h() {} class Bla { mixin wrap!h; } mixin template wrap(alias f) { void blub(alias g = f)() { g(); } } As a workaround, is there a reason you need blub to be parameterized? I mean, f is already part of the template. Yep, a default function is passed to wrap and in most cases blub just calls that one. But sometimes I need blub to use a function other than the default one.
Re: template instance cannot use local 'f' as parameter to non-global template
On 7/13/2011 11:35 PM, Trass3r wrote: Am 13.07.2011, 16:02 Uhr, schrieb Steven Schveighoffer schvei...@yahoo.com: void h() {} class Bla { mixin wrap!h; } mixin template wrap(alias f) { void blub(alias g = f)() { g(); } } As a workaround, is there a reason you need blub to be parameterized? I mean, f is already part of the template. Yep, a default function is passed to wrap and in most cases blub just calls that one. But sometimes I need blub to use a function other than the default one. Don't know it this is the right answer or a possible bug but it does the trick: void h() { import std.stdio; write(h()); } class Bla { mixin wrap!h; } mixin template wrap(alias f) { void blub(typeof(f) g = f) { g(); } } void main() { Bla b = new Bla(); b.blub(); }
Re: template instance cannot use local 'f' as parameter to non-global template
Am 13.07.2011, 16:58 Uhr, schrieb Tyro[a.c.edwards] nos...@home.com: Don't know it this is the right answer or a possible bug but it does the trick: void h() { import std.stdio; write(h()); } class Bla { mixin wrap!h; } mixin template wrap(alias f) { void blub(typeof(f) g = f) { g(); } } void main() { Bla b = new Bla(); b.blub(); } Thanks! Unfortunately it doesn't work with more complex functions: Error: arithmetic/string type expected for value-parameter, not cl_errcode C function(cl_program program, uint param_name, ulong param_value_size, void* param_value, ulong* param_value_size_ret)
Re: template instance cannot use local 'f' as parameter to non-global template
I've seen this error before... *searches memory and old code* Here you go: http://d.puremagic.com/issues/show_bug.cgi?id=3051 I think this is yet another issue. The inner template argument is not something on the stack but it is a template argument.
Re: template instance cannot use local 'f' as parameter to non-global template
On 7/14/2011 12:24 AM, Trass3r wrote: Am 13.07.2011, 16:58 Uhr, schrieb Tyro[a.c.edwards] nos...@home.com: Don't know it this is the right answer or a possible bug but it does the trick: void h() { import std.stdio; write(h()); } class Bla { mixin wrap!h; } mixin template wrap(alias f) { void blub(typeof(f) g = f) { g(); } } void main() { Bla b = new Bla(); b.blub(); } Thanks! Unfortunately it doesn't work with more complex functions: Error: arithmetic/string type expected for value-parameter, not cl_errcode C function(cl_program program, uint param_name, ulong param_value_size, void* param_value, ulong* param_value_size_ret) I gusss the simplest example of the problem you're experiencing would be this: void h() { import std.stdio; write(h()); } void function() fp = h; class Bla { mixin wrap!(fp); } mixin template wrap(alias f) { void blub() { typeof(f) g = f; g(); // --- source of error [1] } } void main() { Bla b = new Bla(); b.blub(); } edit1.d(19): Error: function expected before (), not g of type uint* C function()* [1] Here you are calling a function pointer which simply returns the address of the function... hence your error! Try calling the function (differencing the pointer as such: (*g)()) and your problem is solved.
Re: template instance cannot use local 'f' as parameter to non-global template
On 7/14/2011 12:24 AM, Trass3r wrote: Am 13.07.2011, 16:58 Uhr, schrieb Tyro[a.c.edwards] nos...@home.com: Don't know it this is the right answer or a possible bug but it does the trick: void h() { import std.stdio; write(h()); } class Bla { mixin wrap!h; } mixin template wrap(alias f) { void blub(typeof(f) g = f) { g(); } } void main() { Bla b = new Bla(); b.blub(); } Thanks! Unfortunately it doesn't work with more complex functions: Error: arithmetic/string type expected for value-parameter, not cl_errcode C function(cl_program program, uint param_name, ulong param_value_size, void* param_value, ulong* param_value_size_ret) I guess the simplest example of the problem you're experiencing would be this: void h() { import std.stdio; write(h()); } void function() fp = h; class Bla { mixin wrap!(fp); } mixin template wrap(alias f) { void blub() { typeof(f) g = f; g(); // --- source of error [1] } } void main() { Bla b = new Bla(); b.blub(); } edit1.d(19): Error: function expected before (), not g of type void function()* [1] Here you are calling a function pointer which simply returns the address of the function... hence your error! Try calling the function pointed to by differencing the pointer as such: (*g)() and your problem is solved.
template instance cannot use local 'f' as parameter to non-global template
Is this a bug? If not, how do you make it work? void h() {} class Bla { mixin wrap!h; } mixin template wrap(alias f) { void blub(alias g = f)() { } } void main() { Bla b = new Bla(); b.blub(); } test.d(18): Error: template instance cannot use local 'f' as parameter to non-global template blub(alias g = f) test.d(18): Error: template instance forward reference of f test.d(18): Error: template instance test.Bla.wrap!(h).blub!(f) error instantiating