简体   繁体   中英

Accessing Protected Attribute of Template Class

The following code doesn't work because the t member function can't access the attribute of its argument object.

How to declare template method t of template class A as a friend function of A?

For the code without template, there is no need to declare friend.

Code:

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);
}

Compiler Error (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

Code without template:

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);
}

You can make all template instantiations friends of one another.

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);
}

A<T> and A<T1> are two different types, if T and T1 are two different types. You might as well replace A<T> with Foo and A<T1> with Bar in such a scenario. At that point it should be fairly obvious why you would need to make Foo and Bar friends (ehm, A<T> and A<T1> where T and T1 are not the same type).

Now, take a look at your error:

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

It's telling you it's calling your t() function on an object of type A<T> , passing in an object of type A<T1> as a parameter, where T=int and T1=float . This makes the object that's calling the function of a different class ( A<int> ) than the class of the object being used as the parameter ( A<float> ), and since they're different classes, they can't access each others' protected members without being friends.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM