www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Templates and delegates trouble

reply Lars Kyllingstad <public kyllingen.NOSPAMnet> writes:
Hello,

I want to make a function (named 'call' in the example below) that calls 
another function (F). I want to allow F to be an ordinary function, a 
delegate, or a functor. I've been able to make it work with functions 
and functors, but not with delegates. Any tips would be greatly appreciated.

I have defined 'call' like this:

     T call(alias F, T=real)(T arg)
     {
         return F(arg);
     }

I can now do like this:

     call!(sqrt)(4.0);

or

     class Sqrt
     {
         real opCall(real x) { return sqrt(x); }
     }

     auto sqrt = new Sqrt;
     call!(sqrt)(4.0);

Both of these examples compile and the function returns 2.0 as expected. 
I can not, however, do this:

     class Sqrt
     {
         real eval(real x) { return sqrt(x); }
     }

     auto sqrt = new Sqrt;
     call!(sqrt.eval)(4.0);

To this, the compiler (GDC) says:

     Error: need 'this' to access member eval

So it would seem that even though eval is a method of the Sqrt class, F 
aliases it as a function pointer. Is there any way of making this work?

-Lars
Oct 07 2008
parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
"Lars Kyllingstad" wrote
 Hello,

 I want to make a function (named 'call' in the example below) that calls 
 another function (F). I want to allow F to be an ordinary function, a 
 delegate, or a functor. I've been able to make it work with functions and 
 functors, but not with delegates. Any tips would be greatly appreciated.

 I have defined 'call' like this:

     T call(alias F, T=real)(T arg)
     {
         return F(arg);
     }

 I can now do like this:

     call!(sqrt)(4.0);

 or

     class Sqrt
     {
         real opCall(real x) { return sqrt(x); }
     }

     auto sqrt = new Sqrt;
     call!(sqrt)(4.0);

 Both of these examples compile and the function returns 2.0 as expected. I 
 can not, however, do this:

     class Sqrt
     {
         real eval(real x) { return sqrt(x); }
     }

     auto sqrt = new Sqrt;
     call!(sqrt.eval)(4.0);

 To this, the compiler (GDC) says:

     Error: need 'this' to access member eval

 So it would seem that even though eval is a method of the Sqrt class, F 
 aliases it as a function pointer. Is there any way of making this work?

You can't alias a delegate like that. Try this: auto sqrt = new Sqrt; auto fn = &sqrt.eval; call!(fn)(4.0); What is happening is you are aliasing the eval function symbol, but not the sqrt instance to call it from. Aliasing isn't exactly like a macro substitution. This might also work (haven't tested it): call!(&sqrt.eval)(4.0); -Steve
Oct 07 2008
parent Lars Kyllingstad <public kyllingen.NOSPAMnet> writes:
Steven Schveighoffer wrote:
 "Lars Kyllingstad" wrote
 Hello,

 I want to make a function (named 'call' in the example below) that calls 
 another function (F). I want to allow F to be an ordinary function, a 
 delegate, or a functor. I've been able to make it work with functions and 
 functors, but not with delegates. Any tips would be greatly appreciated.

You can't alias a delegate like that. Try this: auto sqrt = new Sqrt; auto fn = &sqrt.eval; call!(fn)(4.0);

This works. Thank you!
 What is happening is you are aliasing the eval function symbol, but not the 
 sqrt instance to call it from.  Aliasing isn't exactly like a macro 
 substitution.
 
 This might also work (haven't tested it):
 
 call!(&sqrt.eval)(4.0);

This doesn't work.
Oct 08 2008