访问模板类的受保护属性

时间:2016-09-16 17:04:28

标签: c++ templates friend

以下代码不起作用,因为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);
}

2 个答案:

答案 0 :(得分: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 :(得分:1)

A<T>A<T1>是两种不同的类型,如果TT1是两种不同的类型。在这种情况下,您也可以将A<T>替换为Foo,将A<T1>替换为Bar。在这一点上,为什么你需要让Foo和Bar成为朋友(ehm,A<T>A<T1>,其中TT1不是同一类型,这应该是相当明显的)

现在,看看你的错误:

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

它告诉你它在t()类型的对象上调用你的A<T>函数,传入A<T1>类型的对象作为参数,其中T=int和{{ 1}}。这使得调用不同类(T1=float)的函数的对象比用作参数(A<int>)的对象的类,并且因为它们是不同的类,所以它们不能在没有朋友的情况下访问彼此的受保护成员。