1

我正在尝试实现一个链表。但是当我尝试重载 << 运算符时收到错误消息。这是我的程序:

#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;

}

当我执行此代码时,编译器给我以下错误:

警告:朋友声明 'std::ostream& operator<<(std::ostream&, List*)' 声明了一个非模板函数 [-Wnon-template-friend]

注意:(如果这不是您想要的,请确保已经声明了函数模板并在此处的函数名称后添加 <>)

请帮忙。

4

1 回答 1

1

由于它们采用类模板参数,因此您friends需要是函数模板或函数模板的特化:

// function template friend
template <typename T2>
friend ostream& operator<<(ostream& out, const List<T2>& li);

请注意,通常会重载此运算符以获取引用,而不是指针,如上例所示。

缺点是这可能不够严格:ostream& operator<<(ostream& out, const List<Widget>& li)将成为List<int>. 由于这通常不是所需的行为,因此您可以提供一个模板 specialization,它将友谊限制在T与实例化类相同的范围内:

// 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);
于 2013-09-15T17:06:33.660 回答