您的位置:首页 > 其它

Friend class or function and nested types in class templates

2011-11-16 19:28 806 查看
以下内容依据《C++ primer》编写。

1. Friend declaration in class templates

Three kinds of friend declarations

(1) A nontemplate friend class or friend function, they are friends to all instantiations of the class template 

E.g.

class Foo {
void bar();
};
template <class T>
class QueueItem {
friend class foobar;
friend void foo();
friend void Foo::bar();
// ...
};


(2) A bound friend class template or function template.

E.g.

template <class Type> class foobar{ ... };
template <class Type> void foo( QueueItem<Type> );
template <class Type>
class Queue {
void bar();
// ...
};
template <class Type>
class QueueItem {
friend class foobar<Type>;
friend void foo<Type>( QueueItem<Type> );
friend void Queue<Type>::bar();
// ...
};

Using this method, for every instantiation of  QueueItem, the corresponding friend instantiation for the specified type is a friend to it. For instance, that is to say, foobar<int> is a friend to QueueItem<int> but not a friend to QueueItem.
(3) A unbound friend class template or function template.

E.g.

template <class Type>
class QueueItem {
template <class T>   friend class foobar;
template <class T>   friend void foo( QueueItem<T> );
template <class T>   friend void Queue<T>::bar();
// ...
};


2. Nested Types of class templates
With one class being a nested private type, it becomes inaccessible to the general program except calling its enclosing class. The nested classes are automatically class templates. The mapping between an instantiation for the enclosing class template and
an instantiation of the nested class template is one to one. However, the nested class is not instantiated automatically when the enclosing class template is instantiated.

template <class Type>
class Queue {
// ...
private:
class QueueItem { //nested class
public:
QueueItem( Type val )
: item( val ), next( 0 ) { ... }
Type item;
QueueItem *next;
};
// because QueueItem is a nested type,
// and not a template defined outside of Queue,
// the template argument <Type> can be omitted
// after QueueItem
QueueItem *front, *back;
// ...
}; 
or
template <class T> //this allows a definition like Queue<int>::CL<char>
class Queue { 
private: 
   // class member template 
   template <class Type> 
      class CL 
   { 
      Type member; 
      T mem; 
   }; 
   // ... 
public: 
   // function member template 
   template <class Iter> 
      void assign( Iter first, Iter last ) 
   { 
      while ( ! is_empty() ) 
         remove();  // calls Queue<T>::remove() 
      for ( ; first != last; ++first ) 
        add( *first );  // calls Queue<T>::add( const T & ) 
   } 
}; 


A member template can be defined outside its enclosing class. For example, the class member template CL or the member function template assign() can be defined as follows:
template <class T>
class Queue {
private:
template <class Type> class CL;
// ...
public:
template <class Iter>
void assign( Iter first, Iter last );
// ...
};
template <class T> template <class Type>
class Queue<T>::CL<Type>
{
Type member;
T mem;
};
template <class T> template <class Iter>
void Queue<T>::assign( Iter first, Iter last )
{
while ( ! is_empty() )
remove();
for ( ; first != last; ++first )
add( *first );
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐