Find out what type my class is being converted to for comparisons

ryuukk_ ryuukk.dev at gmail.com
Wed Oct 19 21:36:47 UTC 2022


On Tuesday, 18 October 2022 at 18:53:41 UTC, Matthew Rushworth 
wrote:
> I am in the process of building a matrix class (uni project, 
> with my choice of programming language) and appear to have run 
> into a problem that I'm not too sure how to fix.
>
> My class uses templates to define the shape of the matrix, 
> although I'm not sure if that matters. As part of my class, I 
> included a opEquals, but when I try to assert that a matrix 
> created by multiplying with the identity matrix matches the 
> output (I checked with liberal writeln()s to make sure they do) 
> but my opEquals() function (I moved it out of the class as I 
> kept getting errors saying it was supposed to be non-const, and 
> couldn't figure out how to fix that either) just isn't called.
>
> ---
>
> Matrix code (the only bit of the class used by opEquals):
>
> ```
> class Matrix(size_t X, size_t Y = X){
>     const size_t x_length = X;
>     const size_t y_length = Y;
>
>     double[X*Y] data;
>
>     ...
> }
> ```
>
> The entirety of opEquals:
>
> ```
> /// both matrices have to have an identical shape to compare
> /// each element must be identical to match
> bool opEquals(size_t X, size_t Y)(const Matrix!(X,Y) m1, const 
> Matrix!(X,Y) m2) {
>     for (int i = 0; i < m1.data.length; ++i) if (m1.data[i] != 
> m2.data[i]) return false;
>     return true;
> }
> ```
>
> and the code that excepts:
>
> ```
>     void main() {
>         auto m = new Matrix!(2)();
>         m.data = [1.0,0.0,0.0,1.0].dup;
>         auto n = new Matrix!(2)();
>         n.data = [2.0,3.0,4.0,5.0].dup;
>
>         auto u = mult(m,n);
>         writeln("u.data vs n.data:");
>         for (int i = 0; i < u.data.length; ++i)
>             writeln(u.data[i], "\t", n.data[i]);
>
>
>         // using opEquals() directly is working, but it doesn't 
> seem to be being used
>         //assert(opEquals(u,n),"\"opEquals(u, n)\" is 
> failing."); // this works fine
>         assert(u == n,"\"u == n\" is failing."); // this fails. 
> Why?
>     }
> ```
>
> ---
>
> Any help would be very much appreciated. A way to figure out 
> what the '==' is converting its arguments to would also be 
> great, but I'm not sure it exists (beyond just sitting down and 
> trying to work it out myself, of course)

What's the reason for it being a class? struct makes more sense 
here, plus it'll be faster

If it were a struct, you'd not need any of that, and you can also 
have operator overloading for your mult while also being able to 
check how many row/col at compile time, here an example:

```D
import std;

struct Matrix(size_t X, size_t Y = X)
{
     enum x_length = X; // enum so it's available only at compile 
time
     enum y_length = Y;
     double[X * Y] data;

     // operator overloading
     Matrix opBinary(string op)(Matrix rhs)
     {
         static if (op == "*")
         {
             //
             // ** ADD YOUR MULT OPERATION HERE **
             //
             static if (X == 2)
             {
                 return Matrix();
             }
             else
                 static assert("not supported");
         }
         else
             static assert(0, "Operator " ~ op ~ " not 
implemented");
     }
}

void main()
{
     // check equality by value:
     auto a = Matrix!(2)();
     a.data = 0;
     auto b = Matrix!(2)();
     b.data = 0;

     writeln("are they the same?: ", a == b); // it'll check for 
equality by value

     auto m = Matrix!(2)();
     m.data = [1.0, 0.0, 0.0, 1.0];
     auto n = Matrix!(2)();
     n.data = [2.0, 3.0, 4.0, 5.0];

     // here we can use the * operator!
     auto u = m * n;

     writeln("u.data vs n.data:");

     for (int i = 0; i < u.data.length; ++i)
         writeln(u.data[i], "\t", n.data[i]);
}
```


More information about the Digitalmars-d-learn mailing list