www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Recursive template problem

reply Lars Kyllingstad <public kyllingen.NOSPAMnet> writes:
Hello,

I want to make a template that evaluates to the summed absolute values 
of the elements of an array. In other words, I want something like this:

     real[3] foo;
     real sum = absSum!(foo);

to expand (at compile time) to

     real[3] foo;
     real sum = abs(foo[0]) + abs(foo[1]) + abs(foo[2]);

So, I wrote the following templates:

     private template absSum(real[N] V, ulong N) {
         real absSum = absSum!(V, N-1) + abs(V[N-1]);
     }
     private template absSum(real[N] V, ulong M, ulong N) {
         real absSum = absSum!(M-1, V) + abs(V[M-1]);
     }
     private template absSum(real[N] V, ulong M : 1, ulong N) {
         real absSum = abs(V[0]);
     }

but on compilation I get (for each template!) the error messages

   variable N forward referenced
   Error: Integer constant expression expected instead of N
   Error: Integer constant expression expected instead of N
   Error: Integer constant expression expected instead of N
   variable N forward referenced
   Error: Integer constant expression expected instead of N
   Error: Integer constant expression expected instead of cast(ulong)N
   Error: Integer constant expression expected instead of cast(ulong)N
   Error: arithmetic/string type expected for value-parameter, not real[N]

I haven't a clue why I am getting these messages. Any tips?

Thanks,

-Lars
Jul 29 2008
parent BCS <ao pathlink.com> writes:
Reply to Lars,

 Hello,
 
 I want to make a template that evaluates to the summed absolute values
 of the elements of an array. In other words, I want something like
 this:
 
 real[3] foo;
 real sum = absSum!(foo);
 to expand (at compile time) to
 
 real[3] foo;
 real sum = abs(foo[0]) + abs(foo[1]) + abs(foo[2]);
 So, I wrote the following templates:
 
 private template absSum(real[N] V, ulong N) {
 real absSum = absSum!(V, N-1) + abs(V[N-1]);
 }

right off that should be "const real ..."
 private template absSum(real[N] V, ulong M, ulong N) {
 real absSum = absSum!(M-1, V) + abs(V[M-1]);
 }
 private template absSum(real[N] V, ulong M : 1, ulong N) {
 real absSum = abs(V[0]);
 }
 but on compilation I get (for each template!) the error messages
 
 variable N forward referenced
 Error: Integer constant expression expected instead of N
 Error: Integer constant expression expected instead of N
 Error: Integer constant expression expected instead of N
 variable N forward referenced
 Error: Integer constant expression expected instead of N
 Error: Integer constant expression expected instead of cast(ulong)N
 Error: Integer constant expression expected instead of cast(ulong)N
 Error: arithmetic/string type expected for value-parameter, not
 real[N]

I'm not shure arrays of real are allowd for template args 2 options: CTFE: real AbsSum(real[] args){ real ret=0; foreach(real r;args) if(r > 0) ret += r; else if(r < 0) ret -= r; //else 0 or nan: do nothing return ret; } tuples: template AbsSum(T...) { static if(T.length == 0) const real AbsSum = 0; else { static if(T[0] > 0 const real AbsSum = AbsSum(T[1..$]) + T[0]; else static if(T[0] < 0 const real AbsSum = AbsSum(T[1..$]) - T[0]; else const real AbsSum = AbsSum(T[1..$]); } }
Jul 29 2008