C ++: friend declaration "declares a function without a template

I had a problem reloading the stream operator << , and I could not find a solution:

 template<class T, unsigned int TN> class NVector { inline friend std::ostream& operator<< ( std::ostream &lhs, const NVector<T, TN> &rhs); }; template<class T, unsigned int TN> inline std::ostream& NVector<T, TN>::operator<<( std::ostream &lhs, const NVector<T, TN> &rhs) { /* SOMETHING */ return lhs; }; 

The following error message will appear:

warning: friend declaration 'std :: ostream & operator <(std :: ostream &, const NVector &) declares a function without a template [-Wnon-template-friend]

error: 'std :: ostream & NVector :: operator <(std :: ostream &, const NVector &) must take exactly one argument

How to solve this problem?

Many thanks.

+4
source share
1 answer

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 ) { // code goes here return o; } }; 

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) { /* SOMETHING */ return lhs; }; 
+10
source

Source: https://habr.com/ru/post/1414744/


All Articles