C++学習ノート:16章汎用プログラミング


16.1.5        
          。
template <class T, size_t N> void array_init(T (&arr)[N])
{
	cout << "N = " << N << endl;
	for(size_t i=0; i!=N; i++)
		arr[i] = 0;
}
N        。
  :
int a[30];
array_init(a);
   N 30.

16.1.6       
               ,                      。
                    。           ,             。

16.2    
                         ,     。

  :
             。
                ;                        。

  ,      ,         ,                ,        。         ,             。
           T:
template <typename T> int compare(const T &v1, const T &v2)
{
	if(v1 > v2) return 1;
	if(v1 == v2) return 0;

	return -1;
}

     :
int main()
{
	short a = 10;
	int b = 11;
	compare(a , b);
}
   :error: no matching function for call to ‘compare(int&, short int&)’

               ,                。
template <typename T1, typename T2> int compare(const T1 &v1, const T2 &v2)
{
	if(v1 > v2) return 1;
	if(v1 == v2) return 0;

	return -1;
}

====>         :
const   :   const      ,     const           。
           :              ;               。

  :         ,                 ——             。


                  。


16.2.2          
template <typename T1, typename T2, typename T3> 
T1 compare(const T2 &v1, const T3 &v2)
{
	return v1 + v2;
}

      ,           。
  :     ,  int  short  long      ,        ?
               :
	int m = 100;
	double n  =21.5;
	long x = sum_1<long>(m,n); //         long


16.3       
      ,         ,                 ,              .

          。       ,              ,         cpp    。
                ,       。

               。  :
1       .
                    。       。

2       。
                  。
    ,  export    。


16.4      
       ,            。
           ,             。      Queue<Type>     ,      Queue    Queue<type>。
               ,          。——          ,         。


1        
    :
      template  ,         
         ,  +      
          
template <class T> return-type Queue<T>::member-name
  :
template <class Type> void Queue<Type>::push(const Type &item)
{
	cout << "push: " << item << endl;
}
   Type             ;
  oid;
    Queue<Type>     。
        ,      。


                       ,       。
                            。


16.4.2           
         , Screen   :
template <int hi, int wid> class Screen{
public:
	Screen():screen(hi*wid, '#'),cursor(0), height(hi), width(wid) {
		cout << "new screen1 :width= "<< width << "\theight= "<< height << endl;
	}

	Screen(char c):screen(hi*wid, c),cursor(0), height(hi), width(wid) {
		cout << "new screen2 :width= "<< width << "\theight= "<< height << endl;
	}
private:
	string screen;
	string::size_type cursor;
	string::size_type height, width;
};

//---------------------------------------------------------
16.4.3          
      ,                
1               :            。
	friend class xxx;
2              :             。
	template <class T> friend class Queue;
3                     。
	template <class Type> class Queue;
	friend class Queue<int>;  //       
	 
	//   :     ,                        ,                 。
	//     
	template <class Type> class Queue;
	template <class Type> ostream& operator<<(ostream &os, const Queue<Type> &q); 
	//        
	friend class Queue<Type>; 
	friend ostream& operator<< <Type>(ostream &os, const Queue<Type> &q); 


           ,            。  :
    
template <class Type> void frd_func(const Queue<Type> &q)
{
	cout << "frd func test: " << q.head->item << endl;
}
//       QueueItem<Type> Queue<Type>     ,          。
//       。
template <class Type> void frd_func(const Queue<Type> & q);
//         ,            
friend void frd_func<Type>(const Queue<Type> & q);


4       
                    ,            ,          ,       。
    ,                。


       
//C++ primer plus ...... chapter 15  page490

#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <vector>
#include <utility>
#include <new>
#include <functional>

using namespace std;

//use list to implement Queue

template <class Type> class Queue;
template <class Type> ostream& operator<<(ostream &os, const Queue<Type> &q);
template <class Type> void frd_func(const Queue<Type> & q);

//private class
template <class Type> class QueueItem
{
//public:
	//template <class T> friend class Queue;
	friend class Queue<Type>;
	friend ostream& operator<< <Type>(ostream &os, const Queue<Type> &q);
	friend void frd_func<Type>(const Queue<Type> & q);


	QueueItem(const Type &t):item(t), next(0) { }
	
	Type item;
	QueueItem *next;
};

template <class Type> class Queue
{
public:
	Queue():head(0),tail(0) { cout << "Queue constructor" << endl; }
	Queue(const Queue &q):head(0),tail(0) { 
		cout << "Queue constructor" << endl;
		copy_elems(q); 
	}
	~Queue() { 
		cout << "Queue destructor" << endl;
		destory(); 
	}

	Type& front() { return head->item; }
	const Type& front() const  { return head->item; }
	void push(const Type &);
	void pop();
	bool empty() const { return head == 0; }

	friend ostream& operator<< <Type>(ostream &os, const Queue<Type> &q);
	friend void frd_func<Type>(const Queue<Type> & q);
private:
	QueueItem<Type> *head;
	QueueItem<Type> *tail;

	void destory();
	void copy_elems(const Queue<Type>&);
};

//private functions
template <class Type> void Queue<Type>::destory()
{
	while(!empty())
		pop();
}

template <class Type> void Queue<Type>::copy_elems(const Queue<Type> &orig)
{
	for(QueueItem<Type> *p=orig.head; p ; p=p->next){
		push(p->item);
	}
}

//public functions
//push one item to the tail of queue
template <class Type> void Queue<Type>::push(const Type &item)
{
	cout << "push \t" << item << endl;

	QueueItem<Type> *p = new QueueItem<Type>(item);
	p->next = 0;
	if(empty())
		head = tail = p;
	else{
		tail->next = p;
		tail = p;
	}
}

template <class Type> void Queue<Type>::pop()
{
	QueueItem<Type> *p = head;
	head = head->next;

	cout<<"pop \t" << p->item << endl;
	delete p;
}

//operator, friend function
template <class Type> ostream& operator<<(ostream &os, const Queue<Type> &q)
{
	os << "<";
	QueueItem<Type> *p;
	for(p=q.head; p!=0; p=p->next){
		os << p->item << " ";
	}
	os << ">";

	return os;
}


template <class Type> void frd_func(const Queue<Type> &q)
{
	cout << "frd func test: " << q.head->item << endl;
}
//---------------------------------------------------------
//          
template <int hi, int wid> class Screen{
public:
	Screen():screen(hi*wid, '#'),cursor(0), height(hi), width(wid) {
		cout << "new screen1 :width= "<< width << "\theight= "<< height << endl;
	}

	Screen(char c):screen(hi*wid, c),cursor(0), height(hi), width(wid) {
		cout << "new screen2 :width= "<< width << "\theight= "<< height << endl;
	}
private:
	string screen;
	string::size_type cursor;
	string::size_type height, width;
};


int main(int argc, char const *argv[])
{
	Queue<int> ique;
	int a = 12;
	int b = 34;
	ique.push(a);
	ique.push(b);
	ique.push(int(1231));
	cout << ique << endl;

	frd_func(ique);


	Screen<10, 20> scr1;
	Screen<100, 200> scr2('o');

	return 0;
}