Thread overview
Templates and delegates trouble
Oct 07, 2008
Lars Kyllingstad
Oct 08, 2008
Lars Kyllingstad
October 07, 2008
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
October 07, 2008
"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


October 08, 2008
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.