digitalmars.D.learn - Vector operations doesn't convert to a common type?
- simendsjo (11/11) Apr 16 2011 int[3] a = [1,2,4];
- simendsjo (47/58) Apr 16 2011 I tried using a template mixin to avoid having to type this all over,
- Philippe Sigaud (20/23) Apr 17 2011 Try this:
- bearophile (4/15) Apr 16 2011 Vector ops are often implemented in assembly, and despite they are less ...
int[3] a = [1,2,4]; float[3] b = [1,2,4]; float[3] c; // Why doesn't this work? c = a[] + b[]; // Error: incompatible types for ((a[]) + (b[])): 'int[]' and 'float[]' // When this works? c[0] = a[0] + b[0]; c[1] = a[1] + b[1]; c[2] = a[2] + b[2]; assert(c == [2,4,8]);
Apr 16 2011
On 16.04.2011 12:12, simendsjo wrote:int[3] a = [1,2,4]; float[3] b = [1,2,4]; float[3] c; // Why doesn't this work? c = a[] + b[]; // Error: incompatible types for ((a[]) + (b[])): 'int[]' and 'float[]' // When this works? c[0] = a[0] + b[0]; c[1] = a[1] + b[1]; c[2] = a[2] + b[2]; assert(c == [2,4,8]);I tried using a template mixin to avoid having to type this all over, but I cannot get it to work.. I think I have something wrong with my alias usage, but that's just speculating :) mixin template ArrayVectorOp(string op, alias dest, alias a, alias b, int I) if(dest.length == a.length && dest.length == b.length && I >= 1 && I <= dest.length) { // dest[I-1] = a[I-1] op b[I-1] mixin(dest.stringof~"["~(I-1).stringof~"]" " = " ~a.stringof~"["~(I-1).stringof~"]" ~op ~b.stringof~"["~(I-1).stringof~"];"); static if(I > 1) mixin ArrayVectorOp!(op, dest, a, b, I-1); } void main() { int[3] a = [1, 2, 3]; float[3] b = [2.1, 3.2, 4.3]; float[3] c; mixin ArrayVectorOp!("+", c, a, b, a.length); assert(c == [3.1, 5.2, 7.3]); } Gives the following output: t.d(4): no identifier for declarator c[3 - 1] t.d(4): Error: c is used as a type t.d(4): Error: cannot implicitly convert expression (cast(float)a[2u] + b[2u]) o f type float to const(_error_[]) t.d(4): no identifier for declarator c[2 - 1] t.d(4): Error: c is used as a type t.d(4): Error: cannot implicitly convert expression (cast(float)a[1u] + b[1u]) o f type float to const(_error_[]) t.d(4): no identifier for declarator c[1 - 1] t.d(4): Error: c is used as a type t.d(4): Error: cannot implicitly convert expression (cast(float)a[0u] + b[0u]) o f type float to const(_error_[]) t.d(11): Error: mixin t.main.ArrayVectorOp!("+",c,a,b,3u).ArrayVectorOp!(op,c,a, b,2).ArrayVectorOp!(op,c,a,b,1) error instantiating t.d(11): Error: mixin t.main.ArrayVectorOp!("+",c,a,b,3u).ArrayVectorOp!(op,c,a, b,2) error instantiating t.d(18): Error: mixin t.main.ArrayVectorOp!("+",c,a,b,3u) error instantiating
Apr 16 2011
On Sat, Apr 16, 2011 at 13:37, simendsjo <simen.endsjo pandavre.com> wrote:I tried using a template mixin to avoid having to type this all over, but I cannot get it to work.. I think I have something wrong with my alias usage, but that's just speculating :)Try this: auto arrayOp(string op, A, B, int N, int n = 0)(A[N] a, B[N] b) { static if (n < N - 1) mixin("return [a[n] " ~ op ~ " b[n]] ~ arrayOp!(op,A,B,N,n+1)(a, b);"); else mixin("return [a[n] " ~ op ~ " b[n]];"); } void main() { int[3] a = [1,2,4]; float[3] b = [1,2,4]; auto c = arrayOp!"+"(a,b); writeln(c); } I had to resort to the N/n kludge, because of A[N] <-> A[] incompatibilities. Note that this could easily be extend to accept any string function (ala std.algorithm) and any number of arrays. Philippe
Apr 17 2011
simendsjo:int[3] a = [1,2,4]; float[3] b = [1,2,4]; float[3] c; // Why doesn't this work? c = a[] + b[]; // Error: incompatible types for ((a[]) + (b[])): 'int[]' and 'float[]'// When this works? c[0] = a[0] + b[0]; c[1] = a[1] + b[1]; c[2] = a[2] + b[2]; assert(c == [2,4,8]);Vector ops are often implemented in assembly, and despite they are less flexible, they sometimes lead to more efficiency (if the arrays are large). The second example uses normal D code, that's much more flexible. Bye, bearophile
Apr 16 2011