I'm trying to wrap my head around why there is an issue trying to compile this
#include <iostream>
template <unsigned int ROWS,unsigned int COLS>
class Matrix{
public:
double dotProd(const Matrix<1,COLS>& other){
static_assert(ROWS==1,"dotProd only valid for two vectors");
return COLS;//place holder for dot product with row vectors
}
double dotProd(const Matrix<ROWS,1>& other){
static_assert(COLS==1,"dotProd only valid for two vectors");
return ROWS;//place holder for dot product with col vectors
}
};
int main(){
Matrix<1,32> bob;
Matrix<1,32> fred;
std::cout<<bob.dotProd(fred)<<std::endl;
return 0;
}
which is giving me this error:
overloadedTemplateMethod2.cpp: In instantiation of ‘class Matrix<1u, 1u>’:
overloadedTemplateMethod2.cpp:17:32: required from here
overloadedTemplateMethod2.cpp:9:16: error: ‘double Matrix<ROWS,COLS>::dotProd(const Matrix<ROWS, 1u>&) [with unsigned int ROWS = 1u; unsigned int COLS = 1u]’ cannot be overloaded
double dotProd(const Matrix<ROWS,1>& other){
^
overloadedTemplateMethod2.cpp:5:16: error: with ‘double Matrix<ROWS, COLS>::dotProd(const Matrix<1u, COLS>&) [with unsigned int ROWS = 1u; unsigned int COLS = 1u]’
double dotProd(const Matrix<1,COLS>& other){
^
I understand that the template filling out the parameters would cause the second function to resolve to double dotProd(const Matrix<1,1>& other)
but I would think the other one should resolve to double dotProd(const Matrix<1,32>& other)
, not Matrix<1,1>
again.
what's going on here?
A template function can be overloaded either by a non-template function or using an ordinary function template.
You may overload a function template either by a non-template function or by another function template. The function call f(1, 2) could match the argument types of both the template function and the non-template function.
Definition. As per the standard definition, a template class in C++ is a class that allows the programmer to operate with generic data types. This allows the class to be used on many different data types as per the requirements without the need of being re-written for each type.
A non-template class can have template member functions, if required. Notice the syntax. Unlike a member function for a template class, a template member function is just like a free template function but scoped to its containing class.
When you do this:
bob.dotProd(fred)
The dotProd
functions are instantiated to resolve the call for Matrix<1,32>
.
We can say that (disclaimer: it's not exactly how it works, but it gives the idea of what's happening under the hood) they end up being declared as:
double dotProd(const Matrix<1,32>& other);
double dotProd(const Matrix<1,1>& other);
Ignore the first one and let's concentrate on the second one. It requires a new specialization of Matrix
, that is: Matrix<1,1>
.
If you consider such a specialization, what are the declarations you would obtain for dotProd
if you replace template parameters with actual values?
double dotProd(const Matrix<1,1>& other); // Matrix<1, COLS>
double dotProd(const Matrix<1,1>& other); // Matrix<ROWS, 1>
That is, you end up declaring an overloaded function that doesn't differ in its list of parameters. Thus the error.
You can obtain exactly the same error if you replace the body of your main
function with the following line:
Matrix<1,1> someone;
In other terms, your class template Matrix
is ill-formed in those cases where COLS
and ROWS
are equal.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With