算法库的使用细节

算法库在使用的时候,有时不用关心其具体实现,有时却不得不关心.

不用关心,有find等.(说不关心细节,并不是说连其功能都可不晓.而是说其内部的实现.如果我们使用这个函数时,无需过多深入).

然而,算法库还有一些函数,如果你不知晓其内部实现的原理,只是知道它的功能,在使用上可能就达不到预期的目的.这类的函数有:remove_if等.

还是举例说明吧!

例子一:

class Int_Example

{

private:

         int_iVal;

public:

         Int_Example( intinitValue ):_iVal( initValue ){}

         int operator()()

         {

                   return_iVal ++;

         }

};

int main()

{

         vector<int>coll;

         generate_n( back_inserter( coll),10,Int_Example( 1 ) );

         copy(coll.begin(),coll.end(),ostream_iterator<int>(cout," ) );

         return0;

}

输入结果:

1 2 3 4 5 6 7 8 9 10

对于结果,我们先来看看generate_n实际上做了些什么操作:

template<class _OutIt,

         class_Diff,

         class_Fn0> inline

         void_Generate_n(_OutIt _Dest, _Diff _Count, _Fn0 _Func)

         {       // replace [_Dest, _Dest + _Count) with _Func()

         for (;0 < _Count; --_Count, ++_Dest)

                   *_Dest = _Func();

         }

首先,仿函数(function object)都是具有状态的,从原始术语我们很容易得知,可以把它当做一般的类.对象

算法库generate_n把Int_Example(1)传递给_Func,而由源码可以得知,此仿函数的状态其实是变化的.第一次是1,第二次为2.第三次为3...

所以才有上面所示结果.

之所以把generate_n挑出来,是因为这个函数有做”特殊”的操作,唯一需要注意的是仿函数状态改变.了.

那么读者可能就会问了,难道存在其他的算法,使得仿函数不变的?

这里我们就引入remove_if.

同样我们也先看一个例子:

class Int_Example

{

private:

         int_iVal;

         intcount;

public:

         Int_Example( intinitValue ):_iVal( initValue ),count( 0 ){}

         bool operator()( int )

         {

                   return++count == _iVal;

         }

};

int main()

{

         vector<int>coll;

         for ( int i = 0;i < 10; ++ i )

         {

                   coll.push_back( i );

         }

         vector<int>::iteratorpos = remove_if( coll.begin(),coll.end(),Int_Example( 3 ) );

         coll.erase( pos,coll.end() );

 

         copy(coll.begin(),coll.end(),ostream_iterator<int>(cout," ) );

         system( "pause");

         return0;

}

输出结果:

0 1 3 4 6 7 8 9

照上给出remove_if的实现:

template<class _FwdIt,

         class_Pr> inline

         _FwdIt remove_if(_FwdIt _First, _FwdIt_Last, _Pr _Pred)

         {       // remove each satisfying _Pred

         _First = _STD find_if(_First, _Last,_Pred);

         if(_First == _Last)

                   return(_First);  //empty sequence, all done

         else

                   return(_Rechecked(_First,

                            _Remove_if(_Unchecked(_First),_Unchecked(_Last), _Pred)));

         }

请注意的是:_First的取值是依靠find_if来得到的,此时会将_Pred副本的状态改变.此时_First指向value为2,程序接着继续往下走,注意此时_Pred的只并没有改变,其内部直_iVal,count分别为3和0.

这是函数调用_Remove_if,将cout增至3,然后删除找到的这两个数:2和5.

总结:当算法库需要用到仿函数时,要特别注意其状态.有些算法不会改变其状态,有些则不然.

你可能感兴趣的:(算法库的使用细节)