If I omit the template <T> the compiler gives me warning that I'm creating a non-template function.
I read from a book that for some compilers, we have to add the line template <class T>, but my compiler complains that this shadows template parm 'class T'.
When I change it to template <T> it doesn't give me errors, but is it the right way?
You don't actually need the function to be explicitly templated since it already is templated by virtue of the template class. I think that will solve the problem.
And to answer your question, since the class is templated, writing Matrix tells the compiler that you really mean Matrix<T> where T is the type the class was instantiated with.
Typically, you'd do something like:
1 2
template< typename U >
Matrix operator+( const Matrix<U>& ) const;
(Note use of U and not T)
to allow the user to add a matrix instantiated with a different type. For example, the above declaration would allow the following to compile:
1 2 3 4
Matrix<double> a;
Matrix<int> b;
cout << ( a + b ); // calls operator+(const Matrix<U>& ) const [with U = int]
now anywhere you want to reference a C, technically you have to write C<some-type>, right?
But the language allows you to be a little lazier inside the class:
1 2 3 4 5
template< typename Foobar >
class C {
public:
void frobnicate( const C& );
};
Note in the declaration it just says "C". But technically this is impossible, because C is a template class. The language allows this and defines this implicitly to mean C<Foobar>. (There is nothing magical about 'T' or 'U').
But what if you didn't want it to mean C<Foobar>? Then you'd do:
1 2 3 4 5 6
template< typename Foobar >
class C {
public:
template< typename SomeOtherType >
void frobnicate( const C<SomeOtherType>& );
};
It might be that SomeOtherType == Foobar, or it might not. Either way would compile as far as this declaration is concerned.