Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Templated class parameter overloading

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?

like image 417
Austin_Anderson Avatar asked Jul 17 '17 16:07

Austin_Anderson


People also ask

Can class templates be overloaded?

A template function can be overloaded either by a non-template function or using an ordinary function template.

How do you overload a class template in C++?

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.

What is a templated class?

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.

Can a non templated class have a templated member function?

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.


1 Answers

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.

like image 136
skypjack Avatar answered Oct 23 '22 20:10

skypjack