在类模板中可以出现三种友元声明,每一种都声明了与一个或多个实体(指的是友元) 的友元关系:
(1)声明普通非模板类或函数为友元
(2)声明类模板或函数模板为友元
(3)声明类模板或函数模板的特定实例为友元
1.普通友元
非模板类或非模板函数可以是类模板的友元:
template<class Type>class Bar { //grants access to ordinary,nontemplate class and function friend class FooBar ; friend void fcn() ; //... };
这个声明是说,FoorBar的成员和fcn函数可以访问Bar类的任意实例的private成员和protected成员。
2.一般模板友元关系
友元可以是类模板或函数模板:
template<class Type>class Bar { //grants access to Foo1 or template_fcn1 parameterized by any type template<class T>friend class Foo1; template<class T>friend void tem1_fcn1(const T&); //... };这个声明是说,Foo1类的任意实例可以访问Bar类的任意实例。
对于tem1_fcn1函数模板的话,如果传参传人的是Bar类的实例的话,T就是该实例的类型了。如果传入的不是Bar类的实例的话,那么T就无法推断,如果内部使用Bar<T>的实例或者T类型的实例,就必须显示指定模板参数来调用这个函数。
3.特定的模板友元
除了将一个模板的所有实例设为友元,类也可以给特定实例授予友元:
记住:想要限制对特定实例的友元关系时,必须在可以用友元声明之前声明类或函数。
template<class T>class Foo2 template<class T>void temp1_fcn2(const T&); template<class Type>class Bar { //grants access to a single spcific instance parameterized by char* friend class Foo2<char*>; friend void temp1_fcn2<char*>(char* const&); //... };
template<class T>class Foo3; template<class T>void temp1_fcn3(const T&); template<class Type>class Bar { //each instantiantion of Bar grants access to the //version of Foo3 or temp1_fcn3 instaniated with the same type friend class Foo3<Type>; friend void temp_fcn3<Type>(const Type&); //... };
这些友元定义了Bar的特定实例与使用同一模板实参的Foo3与temp1_fcn3的实例之间的友元关系。每个实例有一个相关的Foo3和temp1_fcn3友元:
Bar<int>bi; //Foo3<int> and temp1_fcn3<int> are friends
Bar<string>bs; //Foo3<string> and temp1_fcn3<string> are friends