1:类模板的具体实现方式:参见P689对于Query模板类如下:template<class type>class Query{public: void query();private: class QueryItem { public: type getA(); type getB(); private: type a; type b; };private: QueryItem *next;//这里不需要什么参数类型了};由于QueryItem属于内部模板类,可以直接使用Query的模板参数。同时作为query的私有类,不需要把Query作为QueryItem类的友元存在,只要
QueryItem提供Query的接口getA,getB就可以了。如果不如此,则把QueryItem类全部作为共有成员存在。
两个类模板(QueryItem, Query)的实例时机:上例中首先我们Query<int> QueryInt,这时候先实例化Query类模板,QueryItem没有被实例化,
只有对next成员解引用的时候才实例化QueryItem类模板。
2:成员模板 P691成员模板分为两种:1类数据成员模板,2类函数成员模板template<class T>class Query{private: template< class Type > class CL<Type> { public: Type m; T n; };
public: template< class It> void assign< It first, It last) { remove(); //call Query<T>::remove() to clear Query<T> while (first!=last) { add(*first); //call Query<T>::add to set Query<T> ++first; }; }; };
对于assign这样的成员函数中,在标准库的vector容器就用到了,例如:int a[] = { 1, 2,3};vector<int> vt(a[0], a[3);其对应原型如下:vector的member functiontemplate <class InputIterator>void assign(InputIterator first, InputIterator last);
Erases all elements contained in self, then inserts new elements from the range [first, last).
对于这样类成员函数模板,对类内的任意成员函数都是适用的。比如构造函数,上述的assign同构造函数形式上的差异仅仅在于名字。
类成员模板在类外的实现。上述assign可以实现如此:template<class T> template <class It>void Query<T>::assign(It first, It last){....};
template<class T> template <class Type>class Query<T>::CL<class Type>{....};
16.8类模板及其编译模式 P695类模板的实例:只有在上下文context要求类模板的完整定义时才被实例。举个例子:new的时候,或者调用成员函数的时候。在仅仅是个引用
或者指针的时候不需要类的完整定义。具体参见16.2节。
另外对于构造函数的初始化,尽量使用构造函数表达式来初始化。因为复杂类型(这里指有构造函数的类成员,如string),不要在构造函数
{}设置,因为这样会构造两次。1:传引用2:初始化表达式
实例化的时机:原文摘如下针对一个特定类型而实例化类模吧不会引起“针对同一类型自动实例化类模板成员的定义”。只有当程序需要知道成员的定义时(即如果嵌套类被使用时要求它的完整类类型或如果调用成员函数,或如果做成员地址,或如果查看静态数据成员的值)成员才会被实例化。
编译模式的分类:1:包含模式。即类模板的定义都放在同一个头文件中实现,可以是作为inline函数,或者不作为inline函数,在头文件中定义。2:分离模式:定义(实现文件)和声明(头文件)分开,这里头文件中需要增加export关键字说明。这个关键字放在头文件中的template关键字前即可(这样整个类模板被export)。例如: Query.hexport template < class T>Query{...};
export关键字的作用:告诉编译器,当使用一个类模板的成员函数实例或者静态数据成员实例时,只“要求”类模板的定义。
针对单个成员的export//--Query.htemplate<class Type>class Query{public: void remove(); void add(const Type &);};
template <class Type>void Query<Type>::remove(){...};
//--Query.cpp#include "query.h"
temlate<class Type>export void Query<Type>::add(..){...}
模板的显示实例申明 explicit instantiation declaration#include "Query.h" //--这里需要提供全部的Query模板类的定义template class Query<int>;对于这样的申明,需要使用编译选项“抑制模板隐式实例化”来避免对同一个模板类多次申明。
16.9模板特化 P700 ~ P704#include <iostream>template <class Type>class Compare{public:Type max(Type a, Type b);} ;
template<class Type>Type Compare<Type>::max(Type a, Type b){ return (a>b)?a:b;} ;
template<>double Compare<double>::max(double a, double b){ return 1;} ;
int main(int argc, char* argv[]){ Compare<int> com; std::cout << com.max(30,20) << std::endl; Compare<double> com_d; std::cout << com_d.max(4.4, 5.5) <<std::endl ; return 0;}
16.11 类模板的名字解析 P705
16.12 名字空间和类模板 P707
16.13 模板数组类 P709