Calling template member function?

Paul Backus snarwin at gmail.com
Tue Apr 19 15:46:49 UTC 2022


On Tuesday, 19 April 2022 at 13:36:26 UTC, Andrey Zherikov wrote:
> I want to migrate my library API from standalone function that 
> takes delegate as argument to a template member function that 
> takes delegate as a template parameter but compiler errors out. 
> Here is code example:
> ```d
> import std.stdio;
>
> template T(P)
> {
>     static void f_new(alias func)()
>     {
>         func();
>     }
> }
>
> void f(FUNC)(FUNC func)
> {
>     T!int.f_new!(() => func());
> }
>
> void main()
> {
>     f(function () { __LINE__.writeln; });
> }
> ```
>
> Compiler error:
> ```
> onlineapp.d(7): Error: `static` function `onlineapp.f!(void 
> function() @safe).f.f_new!(delegate () @safe
> {
> (*func)();
> return ;
> }
> ).f_new` cannot access delegate `__lambda2` in frame of 
> function `onlineapp.f!(void function() @safe).f`
> onlineapp.d(13):        `__lambda2` declared here
> onlineapp.d(13): Error: template instance `onlineapp.f!(void 
> function() @safe).f.f_new!(delegate () @safe
> {
> (*func)();
> return ;
> }
> )` error instantiating
> onlineapp.d(18):        instantiated from here: `f!(void 
> function() @safe)`
> ```
>
> What confuses me a lot is that if I remove `template T` then 
> everything works perfectly:

The message is different, but I think this error is probably 
related to the "dual context" issue:

https://issues.dlang.org/show_bug.cgi?id=5710

Basically, `f_new!(() => func())` has two scopes that it "wants" 
to be nested in: `T!int` and `f!(void function() @safe)`. When 
you remove `template T`, there's only one scope, so it's not a 
problem.

If you remove `static` from `f_new`, you get an error message 
talking about this explicitly:

```
onlineapp.d(5): Deprecation: function `onlineapp.f!(void 
function() @safe).f.f_new!(delegate () @safe
{
(*func)();
return ;
}
).f_new` function requires a dual-context, which is deprecated
onlineapp.d(13):        instantiated from here: `f_new!(delegate 
() @safe
{
(*func)();
return ;
}
)`
onlineapp.d(18):        instantiated from here: `f!(void 
function() @safe)`
onlineapp.d(13): Error: function `onlineapp.f!(void function() 
@safe).f.f_new!(delegate () @safe
{
(*func)();
return ;
}
).f_new` is a nested function and cannot be accessed from 
`onlineapp.f!(void function() @safe).f`
```


More information about the Digitalmars-d-learn mailing list