There are two different problems in the code: firstly, the declaration of friend
(as clearly stated, maybe not so clear) declares one non-template function as a friend. That is, when you create an instance of the NVector<int,5>
template, it declares the non-template function std::ostream& operator<<(std::ostream&,NVector<int,5>)
as a friend. Please note that this is different from the declaration of the template function that you provided as a friend.
I would recommend you define a friend function inside the class definition. You can learn more about this in this.
template <typename T, unsigned int TN> class NVector { friend std::ostream& operator<<( std::ostream& o, NVector const & v ) {
Alternatively, you can select other options:
- declare the
operator<<
template as a friend (will provide access to all instances of the template), - declare a specific instance of this template as a friend (more cumbersome to write) or
- Avoid friendship by providing a public
print( std::ostream& )
member function print( std::ostream& )
and calling it from an operator<<
template that is not related to another. I would still decide to make friends with the non-template function and provide a definition inside the template class.
The second problem is that if you want to define an operator outside the left-side argument class, the operator is a free function (not related to the class) and therefore should not be qualified:
template<class T, unsigned int TN> inline std::ostream& operator<<(std::ostream &lhs, const NVector<T, TN> &rhs) { return lhs; };
source share