[C++]模板与泛型编程(3)

来源:互联网 发布:福禄克网络 dsx 8000 编辑:程序博客网 时间:2024/05/21 05:19

成员模板

普通(非模板)类的成员模板
我们设计一个类,包含一个重载的函数调用运算符,它接受一个指针并对此指针执行delete。与默认删除器不同,我们还在删除器被执行时打印一条信息。

class DebugDelet{public:    DebugDelet(std::ostream &s =std::cerr):os(s){}    //与任何函数模板一样,T的类型有编译器推断    template <typename T>    void operator()(T *p) const    {os <<"deleting unique_ptr" << std::endl; delete p;}private:    std::ostream os;};double *p = new double;DebugDelete d;  //可像delete表达式一样使用的对象d(p);   //调用DebugDelete::operator()(double*),释放pint* ip = new int;//在一个临时DebugDelete对象上调用operator()(int*)DebugDelete()(ip);//也可以将DebugDelete用作unique_ptr的删除器。unique_ptr<int,DebugDelete> p(new int, DebugDelete());

这里传入unique_ptr的删除器还可以用函数,
void DebugDelete2(double *d){
cout << “Deleter called\n”;
delete d;
}
unique_ptr

类模板的成员模板

以Blob为例,我们为Blob类定义一个构造函数,它接受两个迭代器,表示要拷贝的元素的范围。

template<typename T>class Blob{    template<typename It>    Blob(It b, It e);};

在类的外部定义时,必须同时提供类模板和函数模板的模板参数列表。

template<typename T>    //类模板的参数template<typename It>Blob<T>::Blob(It b,It e):data(std::make_shared<std::vector<T>>(b,e)){}

控制实例化

在大系统中,在多个文件中实例化相同模板的开销可能非常严重。在新标准中,我们可以通过显示实例化(explicit instantiation)来避免这种开销。

extern template declaration;    //实例化声明template declaration;   //实例化定义

declaration是一个类或函数声明,其中所有模板参数已被替换为模板参数。例如,

//实例化声明与定义extern template class Blob<string>;     //声明template int compare(const int&, const int&);   //定义

extern声明就表示承诺会在程序其他位置有该实例化的一个非extern声明(定义)。

//Application.cc//这些模板类型必须在程序的其他位置进行实例化extern template class Blob<string>;extern template int compare(const int&, const int&);Blob<string> sa1,sa2;   //实例化会出现在其他位置//Blob<int>及其接受initializer_list的构造函数将在本文件中实例化Blob<int> a1={1,2,3};Blob<int> a2(a1);   //拷贝构造函数在本文件中实例化int i = compare(a1[0],a2[0]);   //实例化出现在其他位置
//templateBuild.cc//实例化文件必须为每个在其他文件中声明为extern的类型和函数提供一个(非extern)的定义template int compare(const int&,const int&);templalte class Blob<string>;   //实例化模板的所有成员

实例化定义会实例化所有成员

与类模板成员函数的实例化不同(一个类模板的成员函数只有在使用到它时才进行实例化,这一特性使得即使某种类型不能完全符合模板操作的要求,我们依然能用该类型实例化类)。一个类模板的实例化定义会实例化所有成员。

0 0