www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - template instance cannot use local 'f' as parameter to non-global

reply Trass3r <un known.com> writes:
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
Jul 12 2011
next sibling parent Trass3r <un known.com> writes:
Anybody an idea?
Jul 13 2011
prev sibling next sibling parent Stephan <spam extrawurst.org> writes:
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.
Jul 13 2011
prev sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Tue, 12 Jul 2011 09:06:56 -0400, Trass3r <un 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
Jul 13 2011
next sibling parent reply Trass3r <un known.com> writes:
Am 13.07.2011, 16:02 Uhr, schrieb Steven Schveighoffer  
<schveiguy 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.
Jul 13 2011
parent reply "Tyro[a.c.edwards]" <nospam home.com> writes:
On 7/13/2011 11:35 PM, Trass3r wrote:
 Am 13.07.2011, 16:02 Uhr, schrieb Steven Schveighoffer
 <schveiguy 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(); }
Jul 13 2011
parent reply Trass3r <un known.com> writes:
Am 13.07.2011, 16:58 Uhr, schrieb Tyro[a.c.edwards] <nospam 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)
Jul 13 2011
parent "Tyro[a.c.edwards]" <nospam home.com> writes:
On 7/14/2011 12:24 AM, Trass3r wrote:
 Am 13.07.2011, 16:58 Uhr, schrieb Tyro[a.c.edwards] <nospam 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.
Jul 13 2011
prev sibling parent Trass3r <un known.com> writes:
 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.
Jul 13 2011