您的位置:首页 > 编程语言 > C语言/C++

C++primer学习:类模板(2)类模板:模板参数,成员模板和控制实例化

2015-11-03 13:31 309 查看

默认模板参数.F代表一个默认的类型
less<T>
。用户也可以自己传入相应的可调用对象.当然返回值必须是bool,同时也必须匹配前面的参数.

template<typename T,typename F = less<T>>
int compare(const T& lhs, const T& rhs, F f = F())
{
return f(lhs,rhs) ? -1: (f(rhs,lhs)? 1:0 ) ;

}


[练习]接受一个容器的引用,打印容器中的元素,使用容器的size_type和size成员来控制打印元素的引用.

void print(const T& x)
{
auto it = x.begin();
using size_type = typename T::size_type;//容器的size_type
for (size_type beg = 0; beg != x.size(); ++beg)
cout << *it++ << endl;//不要使用[],因为很多容器不支持[],比如list.
}


======================================================================================

成员模板:一个类可以包含本身是模板的成员函数,这种成员被称为成员模板,成员模板不能是虚函数.

[练习]:定义一个DebugDelete类,用来作为unique_ptr的删除器类型.

class DebugDelete
{
public:
DebugDelete(ostream& s = cerr) :os(s){}
template<typename T>
void operator()(T *p){
os << "deleting unique_ptr" << endl;
delete(p);
}
private:
ostream& os;//定义了一个引用成员
};
int main()
{
unique_ptr<int,DebugDelete> p(new int(3), DebugDelete());

return 0;
}


[练习]:为Texyquery的shared_ptr成员添加删除器.

Textquery::Textquery(string filename) :text(new StrBlob,DebugDelete())//使用DebugDelete()作为删除器
{}


template <typename T>class Blob
{
//其余一样
/************* 添加接受两个迭代器的构造函数**********/
template<typename Iter> Blob(Iter b, Iter e) : data(make_shared<vector<T>>(b, e)){}
}


======================================================================================

只有模板被使用的时候caihui进行实例化,这一特性意味着在多个对象文件中,当两个或者多个独立编译的源文件使用了相同的模板,并提供了相同的模板参数时,每个文件中就会有该模板的一个实例.

在大系统中,在多个文件中实例化相同模板带来的额外开销可能非常严重.在新标准中,我们可以使用显示实例化来避免这种开销.一个显示实例化有如下形式:

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


当编译器遇到extern模板声明的时候,它不会再本文件中生成实例化代码,将一个实例化声明为extern就意味着在程序其他位置由该实例化的一个非extern声明(定义).

实例化定义会实例化该类模板的所有成员.所以假如NoDefault类没有默认构造函数,那么我们不能实例化定义该vector.因为vector里面很多成员需要默认构造元素.

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: