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