2011-12-17 73 views

回答

4

事情是這樣的:你聲明的朋友是不是一個模板,讓你< <模板的給定實例是不是你聲明的朋友之一。

如果聲明的朋友這樣

template <typename U> //or T, doesn't matter 
friend ostream& operator << (ostream& out, const LinkedList<U>& that); 

然後operator << <int>將是LinkedList<float>的朋友。如果這是不可取的,有這樣的解決方案:

friend ostream& operator <<<T> (ostream& out, const LinkedList<T>& that); 

在這種情況下,只有模板的具體實例是你的朋友,這可能是你所需要的。

This article詳細解釋了話題

+0

謝謝!現在我明白了。 – geniaz1 2011-12-17 15:03:51

2

由於operator<<類的外部定義是實際上一個功能:當我寫的,而不是在類的友元函數的聲明

template <typename T> 
class LinkedList 
{ 
private: 
    Node<T>* head; 
    Node<T>* tail; 
    int size; 

public: 
    LinkedList(); 
    ~LinkedList(); 
    inline T* Front() {return &(this->head);}; 
    inline const T* Front() const {return (const T*)this->head;}; 
    void InsertFirst(const T&); 
    void InsertLast(const T&); 
    void RemoveFirst(); 
    void RemoveLast(); 
    void RemoveItem (const T&); 
    void Sort(); 
    void Clear(); 
    inline bool Exists(const T&) const; 
    bool Empty() const {return this->size==0 ? true : false;}; 
    inline int Size() const {return this->size;}; 
    T* At(const int index); 
    const T* At(int index) const; 
    friend ostream& operator << (ostream& out, const LinkedList<T>& that); 
    T* operator[](const int); 
    const T* operator[](const int) const; 
}; 
. 
. 
. 

template <typename T> 
ostream& operator << (ostream& out, const LinkedList<T>& that) 
{ 
    if (!that.Empty()) 
     for(Node<T>* seeker=that.head; seeker; seeker=seeker->next) 
      out<<seeker->info<<endl; 
    return out; 
} 

出於某種原因,鏈接錯誤消失模板,而類中的朋友聲明不是函數模板。

friend聲明是一個非模板函數,其參數相對於類模板是固定的。

例如,如果你實例化int類模板,然後friend變成這樣:

friend ostream& operator << (ostream& out, const LinkedList<int>& that); 

它告訴「我是這個類的一個朋友的編譯器,我也是非模板功能,你會在課堂外找到我的定義,完全相同的簽名。「你可以看到參數是固定的。

但是當你做這樣的事情:

template <typename U> 
friend ostream& operator << (ostream& out, const LinkedList<U>& that); 

這是有道理的編譯器,因爲它是與operator<<類的外部定義,這也是一個函數模板一致。但是有一個問題:它使得函數模板的每個專業化都成爲該類的一個朋友;意味着當U=float,operator<<可以訪問LinkedList<int>的私人成員時,它應該只能訪問LinkedList<float>的私有成員。所以你看,這是問題所在。

更好的解決方案是:不要使它成爲函數模板,並在類中定義好友本身。

template<typename T> 
class LinkedList 
{ 
    public: 


    friend ostream& operator << (ostream& out, const LinkedList<T>& that) 
    { 
     //definition 
    } 
};