首页 > 代码库 > STL源码分析--仿函数 & 模板的模板参数 & 临时对象

STL源码分析--仿函数 & 模板的模板参数 & 临时对象

STL源码分析—使用的一些特殊语法

关于泛型编程中用到的一些特殊语法,这些语法也适用于平常的模板编程

1、  类模板中使用静态成员变量

Static成员变量在类模板中并不是很特殊,同时这个变量不属于对象,属于实例化以后的这个类类型。每一个实例化对应一个static变量

2、  类模板中可以再有模板成员

3、  模板参数可以根据前一个模板参数而设定默认值

4、  类模板可以拥有非类型的模板参数

所谓非类型的模板参数就是内建型的模板参数

Template <class T,class Alloc = alloc,size_t bufsize =0>最后一个参数就是非类型的模板参数

5、  静态常量整数成员在class内部直接初始化(关于这个点的内容在上一篇文章中有介绍)

6、  关于自增自减操作符重载,它的重载和前置后置有关 返回临时变量 返回引用

7、  STL中的区间都是符合前闭后开区间表示方法

8、  临时对象的产生于运用

所谓临时对象,就是一种无名对象。它的出现如果不在程序员的预期之下(例如任何pass by value操作都会引发copy操作,于是形成一个临时对象),往往造成效率上的负担,但有时候可以制造一些临时对象,却又使得程序干净清爽。可以制造临时对象的方法是:在型别名称之后直接加一对小括号,并可指定初值,例如Sharpe(3,5)或者int(6),其意义相当于用相应的构造函数且不指定对象名称,STL中最常使用这样的技巧在仿函数与算法的搭配上。

Class print

{

Public:

Void operator(){costT& elem}

{

Cout<<elem<<endl;   //operator()重载

}

};

         For_each(vi.begin(),vi.end(),print<int>());

         Print<int>()是一个临时对象,不是一个函数调用操作

         最后一行便是产生“classtemplate实例化”print<int>的一个临时对象。这个对象将被传入for_earch()之中的起作用,当for_earch()结束时,这个临时对象也就结束了它的生命

 

Function call 操作符(operator())

这里直接进入正题说仿函数的事情

STL算法的特殊版本所接收的所谓“条件”或“策略”或“一整组操作”,都是以仿函数形式呈现,所谓仿函数就是使用起来像函数一样的东西,如果你针对某个class进行operator()重载,它就成为一个仿函数,至于成为一个可配接的仿函数,还需要一些努力

Template <class T>

Struct plus{

         Toperator()(const T& x,const T& y) const

{

         Return x+y;

}

};

 

Template <class T>

Struct minus{

         Toperator()(const T& x,const T& y) const

{

         Return x+y;

}

};

Int main()

{

         //产生的仿函数对象

         Plus<int>  plusobj;

         Minus<int>  minusobj;

 

//以下使用仿函数,就像使用一般函数一样

Cout<<plusobj(3,5)<<endl;    //5

Cout<<minus(3,5)<<endl;  // -2

 

//以下直接产生仿函数的临时对象(第一对小括号),并调用之(第二对小括号)

Cout<<plus<int>()(3,3)<<endl;

Cout<<minus<int>()(4,3)<<endl;

}

 

至于模板的模板参数,在定义stack的时候用到过

template <typename T, classSeq=vector<T> >

class myself

{

     private:

     Seq c;

     

     };

也可以这样

template <typename T,template<typename M> class Seq=vector >

class myself

{

     private:

     Seq<T> c;

     

     };

 

也可以这样

 

template <typename T,template<typename M,typename Alloc=std::allocator<T> > classSeq=vector >

class myself

{

     private:

     Seq<T> c;

     

     };

好好揣摩着几种定义方式的技巧

STL源码分析--仿函数 & 模板的模板参数 & 临时对象