Template alias parameters to local variables

via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Wed Sep 17 00:41:06 PDT 2014


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?


More information about the Digitalmars-d-learn mailing list