<div class="gmail_quote">On Fri, Aug 6, 2010 at 21:54, Peter Alexander <span dir="ltr">&lt;<a href="http://peter.alexander.au">peter.alexander.au</a>@<a href="http://gmail.com">gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
Is this a bug, or a limitation of how operator overloads handle generic operands?<br>
<br>
  struct Vec(int N) {}<br>
<br>
  struct Mat(int M, int N)<br>
  {<br>
      Vec!(M) opBinary(string op)(in Vec!(N) rhs)<br>
      {<br>
          return Vec!(M)();<br>
      }<br>
  }<br>
<br>
  void main()<br>
  {<br>
      Vec!(3) v;<br>
      Mat!(3, 3) m;<br>
<br>
      Vec!(3) x = m * v; // Error: incompatible types for m * v<br>
      Vec!(3) y = m.opBinary(&quot;*&quot;)(v); // Works<br>
  }<br>
<br>
Note that if you change the operator signature to:<br>
<br>
  Vec!(3) opBinary(string op)(in Vec!(3) rhs)<br>
<br>
then the first statement also compiles, but of course this makes the program incorrect.<br>
<br>
Is this a bug or a language limitation?<br>
</blockquote></div><br>I don&#39;t know how to classify it. You can help the compiler by defining aliases to types:<br><br>struct Mat(int M, int N)<br> {<br>     alias Vec!N ColumnType;<br>     alias Vec!M RowType;<br><br>
     RowType opBinary(string op)(ColumnType rhs)<br>     {<br>         return RowType();<br>     }<br> }<br><br>And then it works!<br>A nice side-effect is that, given an M, you now have M.ColumType and M.RowType exposed, to do what you want.<br>
<br>Maybe another possibility is to use templates constraints?<br><br>Philippe<br><br><br>