www.digitalmars.com         C & C++   DMDScript  

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

reply simendsjo <simen.endsjo pandavre.com> writes:
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...)
Aug 09 2010
parent Lutger <lutger.blijdestijn gmail.com> writes:
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(); }
Aug 09 2010