On 08/08/2016 12:08 AM, Engine Machine wrote:
On Sunday, 7 August 2016 at 20:48:29 UTC, ag0aep6g wrote:
[...]
Delegates don't necessarily need a GC allocation. They only need it
when they need a closure. Delegates of methods don't need closures.
And when you pass the delegate in a `scope` parameter, no closure is
needed, either.
Well, one can't pick the case the delegate is passed. When I use a
delegate in the nogc context it errs.
Not exactly. When you do something that requires a closure, it errors
out. As I said, a delegate doesn't always require the allocation of a
closure.
This works just fine, and it uses a delegate parameter:
----
@nogc void foo(void delegate(int x) @nogc f) {}
void main() @nogc
{
foo((int x) {});
struct S
{
int y;
void f(int x) @nogc { this.y = x; }
}
S s;
foo(&s.f);
}
----
But this doesn't compile, because the delegate here would need a closure:
----
@nogc void foo(void delegate(int x) @nogc f) {}
void main() @nogc
{
int y;
foo((int x) { y = x; });
}
----
Also note that it's main's @nogc that makes this fail, not foo's or the
parameter's. Remove main's @nogc and it works.
[...]
You're missing an argument there. The second parameter of foo is
`args` which is `string` here. This call works:
foo!string((int x, string s) { }, "", 1);
Yeah, that was just a typeo obvious. That's not the reason it fails.
No. It's exactly the reason it fails. Add a string argument and it works:
----
alias callback(Args) = @nogc void function(int x, Args);
@nogc void foo(Args...)(callback!Args f, auto ref Args args, int extra =
0) {}
void main() @nogc
{
foo!string((int x, string s) { }, "", 1);
}
----
[...]
One thing you need to fix: The `callback` template needs a template
sequence parameter (i.e. `Args...`). Otherwise it takes exactly one type.
I did try that first and it didn't work. it works without ..., and I
figured that it is a template parameter and can also represent a
sequence?
No, without `...`, the template parameter only accepts exactly one type,
not more than one, not none.