www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Templated struct operator overloading

reply Peter Alexander <peter.alexander.au gmail.com> writes:
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
parent Philippe Sigaud <philippe.sigaud gmail.com> writes:
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