Well, I can't say that I actually got deep enough into template specializations to resolve the issues grumpy was talking about. But I at least figured out a way to get around the problem--namely by creating friend template functions that create cofactors for square arrays of the given type (T), and then recursively arrive at determinants for these.

So, my array_determinant definition looks like this:

The big difference here is that size is an INPUT (hence already taken care of when the function compiles) rather than a template parameter.Code:template<typename T> T array_determinant(T** arr, const int size) { if (size > 1) { T det = 0; T*** cofactor_array = new T**[size]; for (int i = 0; i < size; ++i) { cofactor_array[i] = array_cofactor(arr, 0, i, size); } // Laplace expansion on first row for (int i = 0; i < size; ++i) { det += arr[0][i] * array_determinant(cofactor_array[i], size - 1); } for (int i = 0; i < size; ++i) { for (int j = 0; j < size - 1; ++j) { delete [] cofactor_array[i][j]; } delete [] cofactor_array[i]; } delete [] cofactor_array; return det; } else return **arr; }

I hope it's not a horrible ugliness in this code that I still have "if (size > 1)", which (such is my impression anyway) grumpy didn't seem to want to see.

I do think it's pretty ugly having to do all of these deletes. But if we're creating cofactors willy-nilly I don't see much of a way around using dynamic memory allocation, and if you do that, you've got to free up the memory again somewhere, right?

Once you do that, then you get a trivial definition for Matrix determinants:

So, no doubt not the greatest code, but at least a way of doing it that seems to work...Code:template<typename T, int n> T Matrix<T, n>::determinant() const { return array_determinant(content, n); }