2012-01-23 77 views
50

比方說,我創建一個類二叉樹,BT,和我有一個類,它描述了樹,BE的元素,像帶模板班朋友的班級模板,這裏究竟發生了什麼?

template<class T> class BE { 
    T *data; 
    BE *l, *r; 
public: 
... 
    template<class U> friend class BT; 
}; 

template<class T> class BT { 
    BE<T> *root; 
public: 
... 
private: 
... 
}; 

這似乎工作;不過,我對下面發生的事情有疑問。

我最初試圖申報的朋友,因爲

template<class T> friend class BT; 

但它似乎有必要使用U(或大於T其他東西)在這裏,這是爲什麼?這是否意味着任何特定的BT對任何特定的BE類都是朋友?

模板和朋友的IBM頁面上有不同類型的函數但不包括類的朋友關係的示例(並且猜測語法尚未融合到解決方案中)。我希望瞭解如何獲得我希望定義的朋友關係類型的規範。

回答

76
template<class T> class BE{ 
    template<class T> friend class BT; 
}; 

不允許,因爲模板參數不能互相影響。嵌套模板必須具有不同的模板參數名稱。


template<typename T> 
struct foo { 
    template<typename U> 
    friend class bar; 
}; 

這意味着barfoo的朋友,無論bar的模板參數。 bar<char>,bar<int>,bar<float>和其他bar將是foo<char>的朋友。


template<typename T> 
struct foo { 
    friend class bar<T>; 
}; 

這意味着barfoo朋友時bar的模板參數匹配foo的。只有bar<char>將是foo<char>的朋友。


在你的情況下,friend class bar<T>;應該是足夠的。

+2

這種結構在我的代碼 友元類BT 拋出一個錯誤的朋友線 錯誤:「BT」不是一個模板 即使它後來被宣佈爲 模板類BT { ... } –

+1

所以祕密是我需要轉發申報BT以便使用朋友類BT ;行中的BE,但不適用於模板的朋友類BT ;.謝謝您的幫助! –

+16

更具體地說:你必須轉發聲明'模板 BT類;'_before_ BE的定義,然後使用'朋友類BT ;'_side_類BE。 –

-1

在我的情況下,該解決方案正常工作:

template <typename T> 
class DerivedClass1 : public BaseClass1 { 
    template<class T> friend class DerivedClass2; 
private: 
int a; 
}; 

template <typename T> 
class DerivedClass2 : public BaseClass1 { 
    void method() { this->i;} 
}; 

我希望這將是有益的。

+5

當您爲模板參數創建陰影時,該解決方案應該如何正確工作,否則不會將DerivedClass2的朋友訪問權限用於DerivedClass1以供使用? – kornman00

1

爲了籠絡另一個同類型的結構:

template<typename T> 
struct Foo 
{ 
    template<typename> friend struct Foo; 
}; 

注意,在template<typename> friend struct Foo;你不應該寫Ttypename/class;否則會導致模板parm shadowing錯誤。

+3

請改善您的答案。 – swiftBoy

1

這是沒有必要的,所以你如果得到故障點更少命名參數重構:

 template <typename _KeyT, typename _ValueT> class hash_map_iterator{ 
     template <typename, typename, int> friend class hash_map; 
     ...