Reputation: 382
I have a matrix class like this:
template <class Type, size_t x_dim, size_t y_dim>
class mat {
private:
std::array<Type, x_dim * y_dim> m_data;
size_t xdim = x_dim, ydim = y_dim; // xdim=no of cols ydim= no of rows
public:
// normal constructor to make unit matrix
mat() {
for (int i = 0; i < y_dim; i++)
for (size_t j = 0; j < x_dim; j++)
operator()(i, j) = i == j ? 1 : 0;
}
//constructor to take in array
mat(const std::array<Type, x_dim * y_dim> &in) {
assert(in.size() == x_dim * y_dim);
m_data = in;
}
// () overload to access elements of matrix
Type &operator()(const size_t &r, const size_t &c){
assert(r >= 0 && r < y_dim && c >= 0 && c < x_dim);
return m_data[r * xdim + c];
}
// * overload to multiply two matrices
template <size_t lx, size_t ly>
mat<Type, x_dim, ly> operator*(const mat<Type, lx, ly> &in) const {
assert(x_dim == ly);
mat<Type, x_dim, ly> ret;
int i, j, k;
for (i = 0; i < y_dim; i++) {
for (j = 0; j < lx; j++) {
ret(i, j) = 0;
for (k = 0; k < x_dim; k++)
ret(i, j) += operator()(i, k) * in(k, j);
}
}
return ret;
}
#ifdef _MSC_VER
template <>
mat<Type, xdim, 4> operator*<4,4>(const mat<Type, 4, 4> &in) const;
#endif
};
How do I specialize the operator*
function for any mat<Type,4,4>
to remove for loops. I tried code below written outside the class defined above:
template <class Type, size_t x_dim, size_t y_dim>
template <size_t lx, size_t ly>
mat<Type, 4, 4> mat<Type, 4, 4>::operator*<4, 4>(const mat<Type, 4, 4> &in) const {
return mat<Type, 4, 4>({
operator()(0, 0) * in(0, 0) + operator()(0, 1) * in(1, 0) + operator()(0, 2) * in(2, 0) + operator()(0, 3) * in(3, 0),
operator()(0, 0) * in(0, 1) + operator()(0, 1) * in(1, 1) + operator()(0, 2) * in(2, 1) + operator()(0, 3) * in(3, 1),
operator()(0, 0) * in(0, 2) + operator()(0, 1) * in(1, 2) + operator()(0, 2) * in(2, 2) + operator()(0, 3) * in(3, 2),
operator()(0, 0) * in(0, 3) + operator()(0, 1) * in(1, 3) + operator()(0, 2) * in(2, 3) + operator()(0, 3) * in(3, 3),
operator()(1, 0) * in(0, 0) + operator()(1, 1) * in(1, 0) + operator()(1, 2) * in(2, 0) + operator()(1, 3) * in(3, 0),
operator()(1, 0) * in(0, 1) + operator()(1, 1) * in(1, 1) + operator()(1, 2) * in(2, 1) + operator()(1, 3) * in(3, 1),
operator()(1, 0) * in(0, 2) + operator()(1, 1) * in(1, 2) + operator()(1, 2) * in(2, 2) + operator()(1, 3) * in(3, 2),
operator()(1, 0) * in(0, 3) + operator()(1, 1) * in(1, 3) + operator()(1, 2) * in(2, 3) + operator()(1, 3) * in(3, 3),
operator()(2, 0) * in(0, 0) + operator()(2, 1) * in(1, 0) + operator()(2, 2) * in(2, 0) + operator()(2, 3) * in(3, 0),
operator()(2, 0) * in(0, 1) + operator()(2, 1) * in(1, 1) + operator()(2, 2) * in(2, 1) + operator()(2, 3) * in(3, 1),
operator()(2, 0) * in(0, 2) + operator()(2, 1) * in(1, 2) + operator()(2, 2) * in(2, 2) + operator()(2, 3) * in(3, 2),
operator()(2, 0) * in(0, 3) + operator()(2, 1) * in(1, 3) + operator()(2, 2) * in(2, 3) + operator()(2, 3) * in(3, 3),
operator()(3, 0) * in(0, 0) + operator()(3, 1) * in(1, 0) + operator()(3, 2) * in(2, 0) + operator()(3, 3) * in(3, 0),
operator()(3, 0) * in(0, 1) + operator()(3, 1) * in(1, 1) + operator()(3, 2) * in(2, 1) + operator()(3, 3) * in(3, 1),
operator()(3, 0) * in(0, 2) + operator()(3, 1) * in(1, 2) + operator()(3, 2) * in(2, 2) + operator()(3, 3) * in(3, 2),
operator()(3, 0) * in(0, 3) + operator()(3, 1) * in(1, 3) + operator()(3, 2) * in(2, 3) + operator()(3, 3) * in(3, 3)};
});
}
I get this error from intellisense of msvc:
and this error from the compiler:
1>Project\Application\include\maths.h(723,34): warning C4346: 'mat<Type,4,4>::*': dependent name is not a type
How do I solve this?
Upvotes: 1
Views: 97
Reputation: 1015
A member or a member template may be nested within many enclosing class templates. In an explicit specialization for such a member, the member declaration shall be preceded by a
template<>
for each enclosing class template that is explicitly specialized.
Upvotes: 0
Reputation: 122228
I will use a simpler example:
template <typename T,size_t x>
struct foo {
template <size_t y>
foo<T,x+y> operator*(const foo<T,y>& other){ return {};}
};
You cannot specialize foo::operator*
for x==4
without specializing foo
. Though, you can supply a non-member operator*
and overload it:
#include <iostream>
template <typename T,size_t x> struct foo {};
template <typename T,size_t x,size_t y>
foo<T,x+y> operator*(const foo<T,x>& a,const foo<T,y>& b){
std::cout << "general operator*\n";
return {};
}
template <typename T>
foo<T,4> operator*(const foo<T,4>& a,const foo<T,4>& b){
std::cout << "4*4\n";
return {};
}
int main() {
foo<int,4> f;
foo<int,3> g;
f*f;
g*g;
}
4*4
general operator*
Upvotes: 3