aspiringvelociraptor
aspiringvelociraptor

Reputation: 13

Is it possible to write a function which takes template arguments with different initialisations

Sorry for the awkward title, it is quite difficult to phrase in words. What I want to know is:

Suppose I have a template class, such as

template<typename T, int height, int width> class GMatrix

and I want to overload the * operator in order to multiply to matrices together. Of course the two matrices in question don't need to be of the same width and height, just that the height of the right hand matrix be equal to the width of the left hand matrix.

Essentially I want this kind of functionality to be possible:

GMatrix<float, 3, 3> left;
GMatrix<float, 3, 6> right;
GMatrix<float, 3, 6> result = left * right;

Is it possible to write such a function? If so, what might the syntax look like for this?

Thanks for reading.

Upvotes: 1

Views: 48

Answers (2)

Stefano Sanfilippo
Stefano Sanfilippo

Reputation: 33046

A possible way could be making operator* a template function in the dimensions of both operands, like in the following example:

template<typename T, int height, int width>
class GMatrix {
};

template<typename T, int h1, int w1, int h2, int w2>
GMatrix<T, h1, w2>
operator*(GMatrix<T, h1, w1> const& a, GMatrix<T, h2, w2> const& b) {
    return GMatrix<T, h1, w2>(); // Or do something else
}

int main() {
    GMatrix<float, 3, 3> left;
    GMatrix<float, 3, 6> right;
    GMatrix<float, 3, 6> result = left * right;
}

You could also enforce matrix dimensions at parameter level:

template<typename T, int h1, int wh, int w2>
GMatrix<T, h1, w2>
operator*(GMatrix<T, h1, wh> const& a, GMatrix<T, wh, w2> const& b) {
    return GMatrix<T, h1, w2>(); // Or do something else
}

Upvotes: 2

Bathsheba
Bathsheba

Reputation: 234715

It is, even in the C++03 standard. The prototype you want is

template<typename T, int h_left, int w_left, int h_right, int w_right>
GMatrix<T, h_left, w_right>
operator*(const GMatrix<T, h_left, w_left>& left, const GMatrix<T, h_right, w_right>& right);

And have a static assertion of w_left == h_right for clarity in compilation.

Upvotes: 2

Related Questions