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

默认模板参数.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里面很多成员需要默认构造元素.

你可能感兴趣的:(C++primer学习:类模板(2)类模板:模板参数,成员模板和控制实例化)