On Saturday, 13 September 2014 at 11:34:01 UTC, Marc Schütz wrote:
Consider the following code:
alias Sink = scope void delegate(const(char)[]);
private template generateAliases(int __i, __vars...) {
import std.conv : to;
static if(__i < __vars.length)
enum generateAliases = "alias " ~
__vars[__i].stringof ~ " =
__vars[" ~ __i.to!string ~ "];\n" ~
generateAliases!(__i+1, __vars);
else
enum generateAliases = "";
}
template render(string __tpl, __vars...) {
void render(Sink sink) {
static void render2(string __tpl2,
__vars2...)(Sink
sink2 = sink) {
.render!(__tpl2, __vars2)(sink2);
}
void render3(string __tpl2, __vars2...)(Sink
sink2 =
sink) {
.render!(__tpl2, __vars2)(sink2);
}
alias __sink = sink;
mixin(generateAliases!(0, __vars));
//mixin(generateRenderer(__tpl));
alias x = __vars[0];
alias y = __vars[1];
render2!("...", x, y); // ERROR
render3!("...", x, y); // ERROR
}
}
void main() {
import std.stdio;
int a, b;
render!("...", a, b)(s => write(s));
}
Inside the `render` function, which takes a string and several
variables as template parameters, as well as a delegate as
runtime parameter, I want another function to be available,
which
should again accept a string and several aliases (including some
that `render` previously received as aliases). At the same time,
the function should implicitly pick up the sink that has been
passed to `render`. I'm trying to slightly different
implementations, `render2` and `render3`. They both produce
compile errors:
render2:
test.d(16): Error: static function test.main.render!("...", a,
b).render2 cannot access frame of function D main
test.d(29): Error: static function test.main.render!("...", a,
b).render2 cannot access frame of function D main
render3:
test.d(30): Error: template instance render3!("...", a, b)
cannot
use local 'a' as parameter to non-global template render3(string
__tpl2, __vars2...)(Sink sink2 = sink)
I would prefer `render2`, because it is static and thus doesn't
need to allocate a context for the sink. Indeed, it used to
work before this issue was fixed:
https://issues.dlang.org/show_bug.cgi?id=11946
https://github.com/D-Programming-Language/dmd/pull/3884
Now, has this fix gone too far? On first glance, the `render2`
error message seems to make sense, but why doesn't the same
error
occur for `render`?
However, why doesn't at least `render3` work? It's strange local
templates cannot accept local variables as aliases...
Alternatively, does anyone know of another way to achieve what I
want?
Anyone an idea?