digitalmars.D - Templated struct operator overloading
- Peter Alexander (22/22) Aug 06 2010 Is this a bug, or a limitation of how operator overloads handle generic
- Philippe Sigaud (18/40) Aug 06 2010 I don't know how to classify it. You can help the compiler by defining
Is this a bug, or a limitation of how operator overloads handle generic operands? struct Vec(int N) {} struct Mat(int M, int N) { Vec!(M) opBinary(string op)(in Vec!(N) rhs) { return Vec!(M)(); } } void main() { Vec!(3) v; Mat!(3, 3) m; Vec!(3) x = m * v; // Error: incompatible types for m * v Vec!(3) y = m.opBinary("*")(v); // Works } Note that if you change the operator signature to: Vec!(3) opBinary(string op)(in Vec!(3) rhs) then the first statement also compiles, but of course this makes the program incorrect. Is this a bug or a language limitation?
Aug 06 2010
On Fri, Aug 6, 2010 at 21:54, Peter Alexander <peter.alexander.au gmail.com>wrote:Is this a bug, or a limitation of how operator overloads handle generic operands? struct Vec(int N) {} struct Mat(int M, int N) { Vec!(M) opBinary(string op)(in Vec!(N) rhs) { return Vec!(M)(); } } void main() { Vec!(3) v; Mat!(3, 3) m; Vec!(3) x = m * v; // Error: incompatible types for m * v Vec!(3) y = m.opBinary("*")(v); // Works } Note that if you change the operator signature to: Vec!(3) opBinary(string op)(in Vec!(3) rhs) then the first statement also compiles, but of course this makes the program incorrect. Is this a bug or a language limitation?I don't know how to classify it. You can help the compiler by defining aliases to types: struct Mat(int M, int N) { alias Vec!N ColumnType; alias Vec!M RowType; RowType opBinary(string op)(ColumnType rhs) { return RowType(); } } And then it works! A nice side-effect is that, given an M, you now have M.ColumType and M.RowType exposed, to do what you want. Maybe another possibility is to use templates constraints? Philippe
Aug 06 2010