struct Matrix(T, size_t row, size_t col){
alias row Row;
alias col Col;
auto opBinary(string op, M)(in M m) const if(op == "*"){
static assert(Col == M.Row, "Cannot Mix Matrices Of Different Sizes.");
// whatever...
return Matrix!(T, Row, M.Col)();
}
}
void main(){
Matrix!(double, 2, 3) m1 = Matrix!(double, 2, 3)();
Matrix!(double, 3, 2) m2 = Matrix!(double, 3, 2)();
Matrix!(double, 2, 2) m3 = m1 * m2; // ERROR
// Error: cannot implicitly convert expression (m1.opBinary(m2)) of type Matrix!(double,row,col) to Matrix!(double,2,2)
}
Why the error and how can I solve this problem?
The problem is that, currently, templates are instantiated with their argument types, not their parameter types.
If you changed your return statement to:
It will compile, because it was instantiated with
int, notsize_t(which is uint or ulong).This is a long-standing bug and although he previously didn’t like it, Walter recently changed his mind supporting changing this to use the parameter types. Here is the pull request fixing this issue (it will be in the next DMD release), linking various related bugs.