2012-03-13 52 views
2

我們有兩個班級模板:A和B以及一個功能模板f1()。就像這樣:關於班級模板朋友的一些問題

template< class T > 
class A{}; 

template< class T > 
class B 
{ 
    friend class A<T>;   /* Expression 1 */ 
    friend void f1(B<T> &b); /* Expression 2 */ 
}; 

template< class T > 
void f1(B<T> &b) {} 

int main() 
{ 
    A<int> a; 
    B<int> b; 

    f1(b); 

    return 0; 
} 

問題1:表達1製作的專業化與參數T A的朋友B與參數T.專業化的 但如何讓每一個 專業化分工的所有朋友的B?

問題2:如何在類定義之外定義f1? 這樣的代碼將產生一個錯誤:

undefined reference to `f1(B<int>&)' 

問題3:如何使所有的F1()S(誰可以接收B作爲參數的所有專業化) 朋友B的每一個專業化的?

回答

2

問題1:兩個

你真的想這樣做?你想A<int>訪問B<float>?通常你不這樣做,但如果你真的想:

template <typename U> 
friend class A; 

問題2:

2的問題是,你是不是使f1模板的朋友的實例,而是你正試圖做一個非模板化的免費功能f1需要一個B<int>你的朋友。正確的語法交好一個特定的實例是麻煩:

template <typename T> class B; 
template <typename T> void f(B<T>&); 
template <typename T> 
class B { 
    friend void f<T>(B<T>&); 
}; 

問題3:

爲了使f1所有專業的朋友(?再次,你真的想這樣),你可以做同樣的方法作爲類模板:

template <typename U> 
friend void f1(B<U>&); 

更多關於所有這些here

+0

'模板朋友類A'和'模板朋友類A'有什麼區別?我不明白。@David Rodriguez – 2012-03-13 15:53:04

+0

@UniMouS:如果你的意思是編輯,修復一個錯字(我認爲)。這是我幾乎沒有寫過的東西之一,語法也不是那麼簡單,我回顧了很久以前我寫過的其他答案,我用編譯器驗證了*,並且語法一致。 – 2012-03-13 15:56:51

+0

哦,謝謝你的回答,我是C++的初學者,我不太明白這個語法。 @David Rodriguez – 2012-03-13 16:11:31

3

問題1:使用

template <typename U> friend class A; 

代替

friend class A<T>; 

問題2:什麼表情2不會被宣告朋友正常功能服用B,而不是函數模板專業化。要聲明的朋友T的專業化,你需要的朋友子句看到F1的聲明,並添加<>紀念F1是一個特例,而不是一個重載的正常功能,所以

template< class T > 
class B; 
template< class T > 
void f1(B<T> &b); 
template< class T > 
class B 
{ 
    friend void f1<>(B<T> &b); 
}; 

template< class T > 
void f1(B<T> &b) {} 

問題3解決方案是一個組合

class B; 
template< class T > 
void f1(B<T> &b); 
template< class T > 
class B 
{ 
    template <typename U> friend void f1(B<U> &b); 
}; 
+0

偉大的答案,從+10我! – 2012-03-13 15:23:24