问题
I'm trying to implement a linked list. But I'm receiving an error when I try overloading the << operator. This is my program:
#include<iostream>
#include<stdlib.h>
using namespace std;
template<class T> class List;
template<class T>
class Node
{
T data;
Node* next;
public:
Node(T val)
{
data = val;
next = NULL;
}
Node(T val, Node* link)
{
data = val;
next = link;
}
friend class List<T>;
friend ostream& operator<<(ostream& out, List<T>* li);
};
template<class T>
class List
{
Node<T>* first;
Node<T>* last;
public:
friend ostream& operator<< (ostream& out, List<T>* li)
{
if(li->first)
out<<"Empty.\n";
else
{
out<<"Displaying: \n";
Node<T>* p = li->first;
while(p)
{
out<<p->data;
p = p->next;
}
}
return out;
}
List()
{
first = last = NULL;
}
List(T val)
{
Node<T>* l = new Node<T>(val);
first = last = l;
}
void insertHead(T val)
{
if(first)
{
Node<T>* p = new Node<T>(val,first);
first = p;
}
else
first = last = new Node<T>(val);
}
void insertTail(T val)
{
if(first)
{
last->next = new Node<T>(val);
last = last->next;
}
else
first = last = new Node<T>(val);
}
void insertAt(T val, int pos)
{
//check if list is empty.
if(first==NULL)
first = new Node<T>(val);
else
if(pos==1)
insertHead(val);
else
{
Node<T>* curr = first;
int i = 1;
// iterate till position is reached.
while( i<pos )
{
curr=curr->next;
i++;
}
//create new node.
Node<T>* p = new Node<T>(val,curr->next);
//link new node to previous node.
curr->next = p;
}
}
void concatenate(List<T>* m)
{
//m is concatenated to end of *this.
if(first)
{
last->next = m->first;
last = m->last;
}
else
{
first = m->first;
last = m->last;
}
m->first = m->last = 0;
}
void delVal(int pos)
{
//if position is first, delete first node.
if( pos == 1 )
{
Node<T>* p = first;
first = first->next;
if(first==0)
last=0;
free(p);
}
//otherwise, iterate till correct position and delete the node.
else
{
int i = 1;
Node<T>* curr = first;
while( i<pos )
{
curr = curr->next;
i++;
}
Node<T>* p = curr->next;
curr->next = p->next;
if(curr->next==0)
last = curr;
free(p);
}
}
void searchVal(T val)
{
Node<T>* curr = first;
int i = 0;
cout<<"Search: ";
while( curr )
{
if( curr->data==val )
{
cout<<val<<" found at position "<<i<<endl;
break;
}
else
{
curr=curr->next;
i++;
}
}
cout<<endl;
}
void recDisplay(Node<T>* curr)
{
if(curr!=0)
{
cout<<curr->data<<endl;
recDisplay(curr->next);
}
}
void Display()
{
cout<<"Displaying: \n";
recDisplay(first);
}
void Reverse()
{
Node<T>* curr = first;
Node<T>* prev = 0;
while( curr )
{
Node<T>* r = prev;
prev = curr;
curr = curr->next;
prev->next = r;
}
first = prev;
}
~List()
{
Node<T>* p = first;
cout<<"Deleting:"<<endl;
while(first!=0)
{
free(first);
first = p->next;
p = first;
}
}
};
int main()
{
List<int>* l = new List<int>();
l->insertHead(5);
l->insertTail(6);
l->insertTail(7);
cout<<l;
}
When i execute this code, the compiler gives me the following errors:
warning: friend declaration 'std::ostream& operator<<(std::ostream&, List*)' declares a non-template function [-Wnon-template-friend]
note: (if this is not what you intended, make sure the function template has already been declared and add <> after the function name here)
Please help.
回答1:
Since they take a class template argument, your friends
need to be function templates, or specializations of function templates:
// function template friend
template <typename T2>
friend ostream& operator<<(ostream& out, const List<T2>& li);
Note that one would usually overload this operator to take a reference, not a pointer, as in the example above.
The drawback is that this is probably not restrictive enough: ostream& operator<<(ostream& out, const List<Widget>& li)
would be a friend of List<int>
. Since this is not usually the desired behaviour, you can provide a template specialization, which would restrict friendship to the same T
as that with which the class is instantiated:
// function template, declared outside of the class:
template <typename T>
ostream& operator<<(ostream& out, const List<T2>& li);
// function template specialization, declared inside the class:
friend ostream& operator<< <>(ostream& out, const List<T>& li);
来源:https://stackoverflow.com/questions/18814928/overloading-operator-in-c-when-using-templates-in-linked-list-program