我編寫了一個模板鏈表(在.h文件中),並且出現鏈接錯誤。在模板鏈表中使用朋友函數時出現鏈接錯誤
template <typename T> friend ostream& operator << (ostream& out, const LinkedList<T>& that);
我編寫了一個模板鏈表(在.h文件中),並且出現鏈接錯誤。在模板鏈表中使用朋友函數時出現鏈接錯誤
template <typename T> friend ostream& operator << (ostream& out, const LinkedList<T>& that);
事情是這樣的:你聲明的朋友是不是一個模板,讓你< <模板的給定實例是不是你聲明的朋友之一。
如果聲明的朋友這樣
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詳細解釋了話題
謝謝!現在我明白了。 – geniaz1 2011-12-17 15:03:51
由於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
}
};
看來你回答自己... – user1071136 2011-12-17 14:51:51