0

fI have the next template of a matrix class:

template<typename T, int rows, int cols>
struct Matrix{
public:
    Matrix() {
        if (rows == cols)
            LoadIdentity();
    }

    T data[rows][cols];

    void LoadIdentity(){ }

    /* more methods ...  */

}
template<int rows, int cols>
using matrixf = Matrix<float, rows, cols>;
template<int rows, int cols>
using matrixd = Matrix<double, rows, cols>;

And i want to be able to initialize this class like:

void main(){
    matrixf<2, 3> m2x3 = { { 1, 2, 3 }, {4, 5, 6} };
}

If I try this, the compiler says:

E0289 no instance of constructor "vian::Matrix [with T=float, rows=2, cols=3]" matches the argument list

If I remove my default constructor, I get the behaviour that I want, but I lose the posibility of having any constructor.

Matrix() { ... } // If I remove this, I have the behaviour I want

A solution I found was to create a constructor that takes an std::initializer_list, but if I do that, the compiler wont check if the initialier list has the right amount of arguments for a matrix of NxM size.

Edit: Added the LoadIdentity method so it compiles.

  • `void main` -> Is this C++? – Ed Heal Sep 25 '17 at 22:04
  • What us the use case for this code? – Ed Heal Sep 25 '17 at 22:07
  • How about `Matrix(std::array, rows>)` ? – Jarod42 Sep 25 '17 at 22:32
  • @Jarod42 I just tried your suggestion but I dont know if I am doing something wrong. It doesn't compile. Im trying to initialize it as: `matrixd<2, 3> m2x3 = { { {1, 2, 3}, {4, 5, 6} } };` and also tried with `matrixd<2, 3> m2x3 = { {1, 2, 3}, {4, 5, 6} } ;`. But still same compile error. – Luis Almaguer Sep 26 '17 at 18:30
  • @Jarod42 Oh, now I got it working, I have to write it like `matrixd<2, 3> m2x3{ {1, 2, 3, 4, 5, 6} };`. But it still compiles if I dont specify enough arguments. E.g. `matrixd<2, 3> m2x3{ {1, 2, 3, 4} };` – Luis Almaguer Sep 26 '17 at 18:41

1 Answers1

0

The best I could do, was to implement what @Jarod42 suggested. Create a constructor like the way he described:

How about Matrix(std::array<std::array<T, cols>, rows>) ? -Jarod42

Even though it doesn't do what I wanted. I took it as an answer because it is a bit safer than what I was doing before (having a constructor of std::initializer_list). It ensures that you don't pass more arguments than it can take, but allows you to specify less. E.g.

matrixf<2, 3> m2x3{ {1, 2, 3, 4, 5, 6} }; // this compiles.
matrixf<2, 3> m2x3{ {1, 2, 3, 4} }; // this also compiles. Missing values are automatically set to 0.

A downside for this approach is the syntax. I wanted to initialize my matrix class by describing each row with curly braces like:

matrixf<2, 3> m2x3{ {1, 2, 3}, {4, 5, 6} }; // this does not compile.
matrixf<2, 3> m2x3{ { {1, 2, 3}, {4, 5, 6} } }; // this does not compile.