2016-09-16 81 views
0

以下代碼不起作用,因爲t成員函數無法訪問其參數對象的屬性。訪問模板類的受保護屬性

如何聲明模板類A的模板方法t作爲A的朋友函數?

對於沒有模板的代碼,不需要聲明朋友。

代碼:

template <typename T> 
class A{ 
    protected: 
     T a; 
    public: 
     A(int i){ 
      a = i; 
     } 
     template <typename T1> 
     void t(const A<T1> & Bb){ 
      a = Bb.a; 
     } 
}; 
int main(void){ 
    A<int> Aa(5); 
    A<float> Bb(0); 
    Aa.t(Bb); 
} 

編譯器錯誤(ICC TEST.CPP):

test.cpp(11): error #308: member "A<T>::a [with T=float]" (declared at line 4) is inaccessible 
       a = Bb.a; 
        ^
      detected during instantiation of "void A<T>::t(const A<T1> &) [with T=int, T1=float]" at line 17 

代碼,而模板:

class A{ 
    protected: 
     int a; 
    public: 
     A(int i){ 
      a = i; 
     } 
     void t(const A & Bb){ 
      a = Bb.a; 
     } 
}; 
int main(void){ 
    A Aa(5); 
    A Bb(0); 
    Aa.t(Bb); 
} 

回答

3

你可以讓彼此的所有模板實例朋友。

template <typename T> 
class A { 
    protected: 

     // This makes A<int> friend of A<float> and A<float> friend of 
     // A<int> 
     template <typename T1> friend class A; 

     T a; 
    public: 
     A(int i){ 
     a = i; 
     } 
     template <typename T1> 
     void t(const A<T1> & Bb){ 
      a = Bb.a; 
     } 
}; 
int main(void){ 
    A<int> Aa(5); 
    A<float> Bb(0); 
    Aa.t(Bb); 
} 
1

A<T>A<T1>兩種不同的類型,如果TT1是兩種不同的類型。在這種情況下,您可以用FooA<T1>Bar替換A<T>。在那一點上,它應該是相當明顯的,爲什麼你需要讓Foo和Bar的朋友(ehm,A<T>A<T1>,其中TT1不是同一類型)。

現在,來看看你的錯誤:

detected during instantiation of "void A<T>::t(const A<T1> &) [with T=int, T1=float]" 

它告訴你它調用A<T>類型的對象對你t()功能,A<T1>類型的對象作爲參數傳遞,其中T=intT1=float 。這使得調用不同類的函數的對象(A<int>)比用作參數的對象的類(A<float>),並且因爲它們是不同的類,所以它們不能訪問彼此的受保護成員朋友。

+0

感謝您的解釋。 – rxu