16.1.1 函数模板。

模板定义以关键字 template 开始。后接 模板形参表,模板形参表是用尖括号括住一个或多个形参列表,形参之间以逗号分隔。

模板形参可以是表示类型的 类型形参,也可以是 表示常量表达式 的非类型形参。

使用函数模板。

使用函数模板时,编译器会推断哪个或哪些模板实参 绑定到模板形参。

一旦编译器确定了对应的模板实参,就称为:实例化了一个函数模板实例。

inline 函数模板

template <typename T> inline T min(const T& ,const T&);

注意:inline 说明符放在模板形参之后,函数返回类型之前。

16.1.2 定义类模板。

可以像定义函数模板一样,定义类模板。

类模板的使用。

与函数模板由编译自动推导出实参类型不同。使用类模板时,必须为模板形参显式指定实参。

如:Queue< int > qi;

Queue < vector<double> > qc;

编译器使用模板实参来实例化这个类的。

16.1.3模板形参。

模板形参作用域:模板形参的名字,可以在声明为模板形参之后,直到模板声明或定义的末尾处使用。

template < typename T> // T 起效。

class demoClass

{

……

};//T 作用域范围。

模板形参遵循常规名字屏蔽规则。同名的,内层名字屏蔽外层。

与全局作用域中声明的 对象,函数,或类型,同名的模板形参会屏蔽它们的全局名字。

    typedef double T;
     template <class T> T calc(const T &a, const T &b) //此处模板形参T屏蔽全局typedef
     {
          // tmp has the type of the template parameter T
          // not that of the global typedef
          T tmp = a;
          // ...
          return tmp;
     }
16.1.4,模板的 类型形参。
类型形参由关键字 class或typename 后接说明符构成。
这个类型形参,可以作为类型说明符,在模板的任何地方使用,就如同内置类型说明符(如,int,double)
在模板定义内部指定类型。
我们知道,类中可以定义 数据成员,函数成员,以及 类型成员。如STL中的size_type.
当我们要使用一个类型成员时,我们应当显式的指定这个名字是一个类型。
     template <class Parm, class U>
     Parm fcn(Parm* array, U value)
     {
         Parm::size_type * p; // If Parm::size_type is a type, then a declaration
                              // If Parm::size_type is an object, then multiplication
     }
以上用法,编译会以为是一个变量 size_type 与另一个p 相乘。
我们应当显式的告诉编译器,在这里,size_type是一个类型。
通过在类型成员前面加上关键字typename 作为前缀,可以显式告诉编译这个名字是一个类型。
     template <class Parm, class U>
     Parm fcn(Parm* array, U value)
     {
         typename Parm::size_type * p; // ok: declares p to be a pointer
     }

在这里,typename Parm::size_type 就告诉编译,size_type是一个类型名,

typename Parm::size_type *p定义一个指向Parm::size_type类型的指针。

当然,前提是我们这里使用的类Parm有size_type这个类型成员。

16.1.5非类型模板形参。

模板形参不必者是类型。也可以是非类型。

1,函数模板.在调用函数时非类型形参将用值代替,值的类型在模板形参表中指定。

     // initialize elements of an array to zero
     template <class T, size_t N> void array_init(T (&parm)[N])
     {
         for (size_t i = 0; i != N; ++i) {
             parm[i] = 0;
         }
     }

N非类型形参。N的实参由编译器计算得到。

当调用 array_init时,编译器从数组实参计算非类型形参的值:

     int x[42];
     double y[10];
     array_init(x);  // instantiates array_init(int(&)[42]
     array_init(y);  // instantiates array_init(double(&)[10]

模板非类型形参是模板定义内部的常量值。

当模板定义需要一个待定的常量值时,可以使用非类型形参。

 posted on 2011-10-24 15:50  chingliuyu  阅读(288)  评论(0编辑  收藏  举报