Calling template member function?

Steven Schveighoffer schveiguy at gmail.com
Tue Apr 19 16:38:42 UTC 2022


On 4/19/22 11:46 AM, Paul Backus wrote:
> 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.

No, there is no context pointer necessary for a template instantiation, 
without one being artificially introduced via an alias parameter. 
`T!int` is essentially just a namespace, especially since the `P` 
parameter isn't even used.

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

Interesting that `static` does anything there, since it's a no-op.

-Steve


More information about the Digitalmars-d-learn mailing list