digitalmars.D - Templated struct operator overloading
- Peter Alexander <peter.alexander.au gmail.com> Aug 06 2010
- Philippe Sigaud <philippe.sigaud gmail.com> Aug 06 2010
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
--000325558c9ed10932048d2d8c44 Content-Type: text/plain; charset=ISO-8859-1 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 --000325558c9ed10932048d2d8c44 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable <div class=3D"gmail_quote">On Fri, Aug 6, 2010 at 21:54, Peter Alexander <s= pan dir=3D"ltr"><<a href=3D"http://peter.alexander.au">peter.alexander.a= u</a> <a href=3D"http://gmail.com">gmail.com</a>></span> wrote:<br><bloc= kquote class=3D"gmail_quote" style=3D"margin: 0pt 0pt 0pt 0.8ex; border-lef= t: 1px solid rgb(204, 204, 204); padding-left: 1ex;"> Is this a bug, or a limitation of how operator overloads handle generic ope= rands?<br> <br> =A0struct Vec(int N) {}<br> <br> =A0struct Mat(int M, int N)<br> =A0{<br> =A0 =A0 =A0Vec!(M) opBinary(string op)(in Vec!(N) rhs)<br> =A0 =A0 =A0{<br> =A0 =A0 =A0 =A0 =A0return Vec!(M)();<br> =A0 =A0 =A0}<br> =A0}<br> <br> =A0void main()<br> =A0{<br> =A0 =A0 =A0Vec!(3) v;<br> =A0 =A0 =A0Mat!(3, 3) m;<br> <br> =A0 =A0 =A0Vec!(3) x =3D m * v; // Error: incompatible types for m * v<br> =A0 =A0 =A0Vec!(3) y =3D m.opBinary("*")(v); // Works<br> =A0}<br> <br> Note that if you change the operator signature to:<br> <br> =A0Vec!(3) opBinary(string op)(in Vec!(3) rhs)<br> <br> then the first statement also compiles, but of course this makes the progra= m incorrect.<br> <br> Is this a bug or a language limitation?<br> </blockquote></div><br>I don't know how to classify it. You can help th= e compiler by defining aliases to types:<br><br>struct Mat(int M, int N)<br==A0{<br>=A0=A0=A0=A0 alias Vec!N ColumnType;<br>=A0=A0=A0=A0 alias Vec!M R=
=A0=A0=A0=A0 RowType opBinary(string op)(ColumnType rhs)<br>=A0=A0=A0=A0 {<= br>=A0=A0=A0=A0=A0=A0=A0=A0 return RowType();<br>=A0=A0=A0=A0 }<br>=A0}<br>= <br>And then it works!<br>A nice side-effect is that, given an M, you now h= ave M.ColumType and M.RowType exposed, to do what you want.<br> <br>Maybe another possibility is to use templates constraints?<br><br>Phili= ppe<br><br><br> --000325558c9ed10932048d2d8c44--
Aug 06 2010








Philippe Sigaud <philippe.sigaud gmail.com>