Cannot use local xxx as parameter to non-global template.

Lutger lutger.blijdestijn at gmail.com
Mon Aug 9 17:39:12 PDT 2010


simendsjo wrote:

> I'm new, so this is most certainly my fault I guess, but I cannot
> understand the error message...
> I wish to slice an array and store the slices in a tuple.
> 
> auto partitionArray(T)(T[] array, int offset, int len)
> {
> auto pre = array[0 .. offset];
> auto slice = array[offset .. offset+len];
> auto post = array[offset+len .. $];
> 
> return Tuple!(pre, slice, post);
> }
> unittest
> {
> auto val = partitionArray([1,2,3,4], 1, 2);
> }
> 
> typecons.d(255): Error: template instance cannot use local 'post' as
> parameter to non-global template A(U...)

Try this:

auto partitionArray(T)(T[] array, int offset, int len)
{
        auto pre = array[0 .. offset];
        auto slice = array[offset .. offset+len];
        auto post = array[offset+len .. $];
        
        return tuple(pre, slice, post);
}
unittest
{
        auto val = partitionArray([1,2,3,4], 1, 2);
}

Explanation: In D you can pass a template a symbol as a parameter, and the 
parameter will alias simply to that symbol itself. So here you try to 
instantiate a Tuple with three local variables as the compile time parameters. 
The tuple function will infer the types of them instead and wrap them up for 
you.

Instantiating a template with local variables is actually possible, but only if 
the template is declared at global scope, which isn't the case here. It is very 
useful for nested functions, you even instantiate it with anonymous delegates:

template Foo(alias sym)
{
    alias sym Foo;
}

unittest
{
    int number = 1;
    alias Foo!number FooNumber;
    FooNumber++;
    assert(number == 2);
    assert(__traits(identifier, FooNumber) == "number");
    
    alias Foo!( { writeln(number); } ) PrintNumber;
    PrintNumber();
}


More information about the Digitalmars-d-learn mailing list