Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overloading friend operator << for template class

Tags:

c++

operators

I'm trying to overload the operator << as a friend to a template class Pair, but I keep getting a compiler warning saying

friend declaration std::ostream& operator<<(ostream& out, Pair<T,U>& v) declares a non template function 

for this code:

friend ostream& operator<<(ostream&, Pair<T,U>&); 

it gives a second warning as a recommendation saying

if this is not what you intended, make sure the function template has already been declared and add <> after the function name here 

Here is the function definition

template <class T, class U> ostream& operator<<(ostream& out, Pair<T,U>& v) {     out << v.val1 << " " << v.val2; } 

and here is the whole class.

template <class T, class U> class Pair{ public:     Pair(T v1, U v2) : val1(v1), val2(v2){}     ~Pair(){}     Pair& operator=(const Pair&);     friend ostream& operator<<(ostream&, Pair<T,U>&);  private:     T val1;     U val2; }; 

I wasn't sure what to draw from the recommendation warning, other than that maybe I have to put somewhere in the friend declaration. Does anyone know the proper syntax for this? Thanks.

like image 820
trikker Avatar asked Aug 19 '09 02:08

trikker


People also ask

Can we overload << operator?

We can overload the '>>' and '<<' operators to take input in a linked list and print the element in the linked list in C++. It has the ability to provide the operators with a special meaning for a data type, this ability is known as Operator Overloading.

Can we overload << operator in C++?

You can redefine or overload the function of most built-in operators in C++. These operators can be overloaded globally or on a class-by-class basis. Overloaded operators are implemented as functions and can be member functions or global functions. An overloaded operator is called an operator function.

Why must << be overloaded as a friend function?

Why must << be overloaded as a friend function? It is not necessary. It is usually done because this function often accesses the private and protected members of the object it displays. overloaded operator<< or operator>> function.

Is overloading is possible for template functions?

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


2 Answers

You want to make one single instance (called "specialization" in generic terms) of that template a friend. You do it the following way

template <class T, class U> class Pair{ public:     Pair(T v1, U v2) : val1(v1), val2(v2){}     ~Pair(){}     Pair& operator=(const Pair&);     friend ostream& operator<< <> (ostream&, Pair<T,U>&);  private:     T val1;     U val2; }; 

Because the compiler knows from the parameter list that the template arguments are T and U, you don't have to put those between <...>, so they can be left empty. Note that you have to put a declaration of operator<< above the Pair template, like the following:

template <class T, class U> class Pair;  template <class T, class U> ostream& operator<<(ostream& out, Pair<T,U>& v);  // now the Pair template definition... 
like image 183
Johannes Schaub - litb Avatar answered Sep 18 '22 04:09

Johannes Schaub - litb


You declare operator<< as returning an ostream&, but there is no return statement at all in the method. Should be:

template <class T, class U> ostream& operator<<(ostream& out, Pair<T,U>& v) {     return out << v.val1 << " " << v.val2; } 

Other than that, I have no problems or warnings compiling your code under Visual Studio 2008 with warnings at level 4. Oh, there are the classical linker errors, but that is easily bypassed by moving the template function definition to the class declaration, as explained in the C++ FAQ.

My test code:

#include <iostream> using namespace std;  template <class T, class U> class Pair{  public:     Pair(T v1, U v2) : val1(v1), val2(v2){}     ~Pair(){}     Pair& operator=(const Pair&);     friend ostream& operator<<(ostream& out, Pair<T,U>& v)     {         return out << v.val1 << " " << v.val2;     } private:         T val1;     U val2; };  int main() {     Pair<int, int> a(3, 4);     cout << a;       } 
like image 23
Asik Avatar answered Sep 17 '22 04:09

Asik