2016-09-16 80 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